<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <meta name="keywords" content="imlgw,半岛铁盒,blog,Java博客,程序员,个人博客,java開發,程序員,個人博客,Java">
    <meta name="description" content="大悲无泪，大悟无言，大笑无声。">
    <meta name="author" content="Resolmi">
    
    <title>
        
            LeetCode二分查找 |
        
        Tadow
    </title>
    
<link rel="stylesheet" href="/css/style.css">

    <link rel="shortcut icon" href="https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico">
    <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/css/font-awesome.min.css">
    <script id="hexo-configurations">
    let KEEP = window.KEEP || {};
    KEEP.hexo_config = {"hostname":"imlgw.top","root":"/","language":"zh-CN","path":"search.json"};
    KEEP.theme_config = {"toc":{"enable":true,"number":true,"expand_all":true,"init_open":true},"style":{"primary_color":"#0066CC","avatar":"https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png","favicon":"https://static.imlgw.top/blog/20210731/BtJz541CcmJU.ico","article_img_align":"left","left_side_width":"260px","content_max_width":"920px","hover":{"shadow":false,"scale":true},"first_screen":{"enable":true,"background_img":"/images/image.svg","description":"Keep It Simple & Stupid."},"scroll":{"progress_bar":{"enable":true},"percent":{"enable":true}}},"local_search":{"enable":true,"preload":false},"code_copy":{"enable":true,"style":"default"},"pjax":{"enable":true},"lazyload":{"enable":true},"version":"3.4.3"};
    KEEP.language_ago = {"second":"%s 秒前","minute":"%s 分钟前","hour":"%s 小时前","day":"%s 天前","week":"%s 周前","month":"%s 月前","year":"%s 年前"};
  </script>
<meta name="generator" content="Hexo 5.4.0"><link rel="stylesheet" href="/css/prism.css" type="text/css"></head>


<body>
<div class="progress-bar-container">
    
        <span class="scroll-progress-bar"></span>
    

    
        <span class="pjax-progress-bar"></span>
        <span class="pjax-progress-icon">
            <i class="fas fa-circle-notch fa-spin"></i>
        </span>
    
</div>


<main class="page-container">

    

    <div class="page-main-content">

        <div class="page-main-content-top">
            <header class="header-wrapper">

    <div class="header-content">
        <div class="left">
            
            <a class="logo-title" href="/">
                Tadow
            </a>
        </div>

        <div class="right">
            <div class="pc">
                <ul class="menu-list">
                    
                        <li class="menu-item">
                            <a class=""
                               href="/"
                            >
                                首页
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/archives"
                            >
                                归档
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/categories"
                            >
                                分类
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/sbe"
                            >
                                订阅
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/links"
                            >
                                友链
                            </a>
                        </li>
                    
                        <li class="menu-item">
                            <a class=""
                               href="/about"
                            >
                                关于
                            </a>
                        </li>
                    
                    
                        <li class="menu-item search search-popup-trigger">
                            <i class="fas fa-search"></i>
                        </li>
                    
                </ul>
            </div>
            <div class="mobile">
                
                    <div class="icon-item search search-popup-trigger"><i class="fas fa-search"></i></div>
                
                <div class="icon-item menu-bar">
                    <div class="menu-bar-middle"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="header-drawer">
        <ul class="drawer-menu-list">
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/">首页</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/archives">归档</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/categories">分类</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/sbe">订阅</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/links">友链</a>
                </li>
            
                <li class="drawer-menu-item flex-center">
                    <a class=""
                       href="/about">关于</a>
                </li>
            
        </ul>
    </div>

    <div class="window-mask"></div>

</header>


        </div>

        <div class="page-main-content-middle">

            <div class="main-content">

                
                    <div class="fade-in-down-animation">
    <div class="article-content-container">

        <div class="article-title">
            <span class="title-hover-animation">LeetCode二分查找</span>
        </div>

        
            <div class="article-header">
                <div class="avatar">
                    <img src="https://static.imlgw.top/blog/20210731/3C7hCSRR3lfq.png">
                </div>
                <div class="info">
                    <div class="author">
                        <span class="name">Resolmi</span>
                        
                            <span class="author-label">BOSS</span>
                        
                    </div>
                    <div class="meta-info">
                        <div class="article-meta-info">
    <span class="article-date article-meta-item">
        <i class="fas fa-edit"></i>&nbsp;2019-12-06 00:00:00
    </span>
    
        <span class="article-categories article-meta-item">
            <i class="fas fa-folder"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/categories/%E7%AE%97%E6%B3%95/">算法</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    
    
        <span class="article-tags article-meta-item">
            <i class="fas fa-tags"></i>&nbsp;
            <ul>
                
                    <li>
                        <a href="/tags/LeetCode/">LeetCode</a>&nbsp;
                    </li>
                
                    <li>
                        | <a href="/tags/%E4%BA%8C%E5%88%86/">二分</a>&nbsp;
                    </li>
                
            </ul>
        </span>
    

    
    
        <span class="article-wordcount article-meta-item">
            <i class="fas fa-file-word"></i>&nbsp;<span>19.7k 字</span>
        </span>
    
    
        <span class="article-min2read article-meta-item">
            <i class="fas fa-clock"></i>&nbsp;<span>89 分钟</span>
        </span>
    
    
        <span class="article-pv article-meta-item">
            <i class="fas fa-eye"></i>&nbsp;<span id="busuanzi_value_page_pv"></span>
        </span>
    
</div>

                    </div>
                </div>
            </div>
        

        <div class="article-content markdown-body">
            <blockquote>
<p> 从 <a href="http://imlgw.top/2019/05/04/leetcode-shu-zu/">数组专题</a> 中抽取出来的 </p>
</blockquote>
<h2 id="二分搜索"><a href="#二分搜索" class="headerlink" title="二分搜索"></a><em>二分搜索</em></h2><h2 id="704-二分查找"><a href="#704-二分查找" class="headerlink" title="704. 二分查找"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/binary-search/" >704. 二分查找<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个 n 个元素有序的（升序）整型数组 nums 和一个目标值 target  ，写一个函数搜索 nums 中的 target，如果目标值存在返回下标，否则返回 -1。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [-<span class="number">1</span>,<span class="number">0</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">9</span>,<span class="number">12</span>], target = <span class="number">9</span></span><br><span class="line">输出: <span class="number">4</span></span><br><span class="line">解释: <span class="number">9</span> 出现在 nums 中并且下标为 <span class="number">4</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [-<span class="number">1</span>,<span class="number">0</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">9</span>,<span class="number">12</span>], target = <span class="number">2</span></span><br><span class="line">输出: -<span class="number">1</span></span><br><span class="line">解释: <span class="number">2</span> 不存在 nums 中因此返回 -<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>你可以假设 nums 中的所有元素是不重复的</li>
<li>n 将在 [1, 10000]之间</li>
<li>nums 的每个元素都将在 [-9999, 9999]之间</li>
</ul>
<p><strong>解法一</strong></p>
<p>比较经典的二分</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(nums[mid] &gt; target)&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>按照板子来的二分，最后需要后处理一下不存在的情况</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//模板二分</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123; <span class="comment">//排除mid</span></span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left!=nums.length&amp;&amp;nums[left]==target?left:-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="69-x-的平方根"><a href="#69-x-的平方根" class="headerlink" title="69. x 的平方根"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sqrtx/" >69. x 的平方根<i class="fas fa-external-link-alt"></i></a></h2><p>实现 <code>int sqrt(int x)</code> 函数。</p>
<p>计算并返回 <em>x</em> 的平方根，其中 <em>x</em> 是非负整数。</p>
<p>由于返回类型是整数，结果只保留整数的部分，小数部分将被舍去。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">4</span></span><br><span class="line">输出: <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: <span class="number">8</span></span><br><span class="line">输出: <span class="number">2</span></span><br><span class="line">说明: <span class="number">8</span> 的平方根是 <span class="number">2.82842</span>..., </span><br><span class="line">     由于返回类型是整数，小数部分将被舍去。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>二分解法</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">mySqrt</span><span class="params">(x <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    lx := <span class="keyword">int64</span>(x)</span><br><span class="line">    <span class="keyword">var</span> left <span class="keyword">int64</span> = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> right <span class="keyword">int64</span> = lx/<span class="number">2</span> + <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> left &lt; right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> mid*mid &lt; lx &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">            <span class="comment">//向下取整的，所以需要额外判断或者取右中位数</span></span><br><span class="line">            <span class="keyword">if</span> left*left &gt; lx &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">int</span>(mid)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            right = mid</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">int</span>(left)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>还有一种比较好的解法，更加贴合模板</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="comment">//这个其实更能体现模板的好处</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">mySqrt</span><span class="params">(x <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    lx := <span class="keyword">int64</span>(x)</span><br><span class="line">    <span class="keyword">var</span> left <span class="keyword">int64</span> = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> right <span class="keyword">int64</span> = lx/<span class="number">2</span> + <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> left &lt; right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span> + <span class="number">1</span></span><br><span class="line">        <span class="comment">//大于lx的一定不是res可以排除，但是小于的不一定不是，题目是向下取整的</span></span><br><span class="line">        <span class="keyword">if</span> mid*mid &gt; lx &#123; </span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            left = mid</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">int</span>(left)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<blockquote>
<p>牛顿迭代法，还没时间仔细去研究，后面有时间再看看</p>
</blockquote>
<h2 id="35-搜索插入位置"><a href="#35-搜索插入位置" class="headerlink" title="35. 搜索插入位置"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-insert-position/" >35. 搜索插入位置<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个排序数组和一个目标值，在数组中找到目标值，并返回其索引。如果目标值不存在于数组中，返回它将会被按顺序插入的位置。</p>
<p>你可以假设数组中无重复元素。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>], <span class="number">5</span></span><br><span class="line">输出: <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>], <span class="number">2</span></span><br><span class="line">输出: <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>], <span class="number">7</span></span><br><span class="line">输出: <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 4:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>], <span class="number">0</span></span><br><span class="line">输出: <span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>跟谁学笔试现场写的，上面的都是dd（删除了之前的解法）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">searchInsert</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len=nums.length;</span><br><span class="line">    <span class="keyword">int</span> lo=<span class="number">0</span>,hi=len; <span class="comment">//和模板不一样，因为这里是搜索插入位置是可以到达right的</span></span><br><span class="line">    <span class="keyword">while</span>(lo&lt; hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">            hi=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> lo;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//update: 2020.5.18</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">searchInsert</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len=nums.length;</span><br><span class="line">    <span class="keyword">int</span> lo=<span class="number">0</span>,hi=len-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res=hi;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;=target)&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[res]&lt;target?len:res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="153-寻找旋转排序数组中的最小值"><a href="#153-寻找旋转排序数组中的最小值" class="headerlink" title="153. 寻找旋转排序数组中的最小值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/" >153. 寻找旋转排序数组中的最小值<i class="fas fa-external-link-alt"></i></a></h2><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。</p>
<p>( 例如，数组 <code>[0,1,2,4,5,6,7]</code> 可能变为 <code>[4,5,6,7,0,1,2]</code> )。</p>
<p>请找出其中最小的元素。</p>
<p>你可以假设数组中不存在重复元素。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="number">1</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>把最开始写的拉跨解法也放上来吧</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findMin</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span>||nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (nums.length==<span class="number">1</span>||nums[<span class="number">0</span>]&lt;nums[nums.length-<span class="number">1</span>]) &#123;</span><br><span class="line">        <span class="keyword">return</span> nums[<span class="number">0</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>+<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid]&gt;nums[mid-<span class="number">1</span>]) &#123;</span><br><span class="line">            <span class="keyword">if</span> (nums[mid]&gt;nums[<span class="number">0</span>]) &#123;</span><br><span class="line">                left=mid;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                right=mid-<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> nums[mid];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[left];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>说实话，我都不知道咋对的。。。</p>
<p><strong>解法二</strong></p>
<p>模板解法，还是模板写起来清晰舒服</p>
<blockquote>
<p>建议直接看UPDATE</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findMin</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (nums==<span class="keyword">null</span>||nums.length&lt;=<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (nums[mid]&gt;nums[right]) &#123; <span class="comment">//排除mid的分支</span></span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[left];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>需要注意要和右边界比较，和左边界比较不一定正确</p>
<p>比如 <code>1 2 3 4 5</code> 和<code>2 3 4 5 1</code> 两个的中点都大于左边界，但是你无法确定此时应该如果缩短区间，除非做特判，但是那样就麻烦了</p>
<p><strong>UPDATE: 2020.7.22</strong></p>
<p>最小值的特点就是肯定是小于等于nums的最后一个元素，这里没有重复的元素，所以最小值肯定是小于最后一个元素的，除非最后一个就是最小的元素，这种情况我们设置为res的初始值，这样我重写后我感觉更好理解了，进阶版的只需要在这个的基础上稍加改动就行了</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findMin</span><span class="params">(nums []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">var</span> left, right = <span class="number">0</span>, n - <span class="number">1</span></span><br><span class="line">    <span class="keyword">var</span> res = right<span class="comment">//对nums[n-1]就是最小值做兜底</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> nums[mid] &lt; nums[n<span class="number">-1</span>] &#123;</span><br><span class="line">            res = mid</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[res]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>同理也可以和左边界比较，最小值一定是小于等于nums[0]的</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findMin</span><span class="params">(nums []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">var</span> left, right = <span class="number">0</span>, n - <span class="number">1</span></span><br><span class="line">    <span class="keyword">var</span> res = left <span class="comment">//对nums[0]就是最小值做兜底</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> nums[mid] &lt; nums[<span class="number">0</span>] &#123;</span><br><span class="line">            res = mid</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[res]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="154-寻找旋转排序数组中的最小值-II"><a href="#154-寻找旋转排序数组中的最小值-II" class="headerlink" title="154. 寻找旋转排序数组中的最小值 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/" >154. 寻找旋转排序数组中的最小值 II<i class="fas fa-external-link-alt"></i></a></h2><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。</p>
<p>( 例如，数组 <code>[0,1,2,4,5,6,7]</code> 可能变为 <code>[4,5,6,7,0,1,2]</code> )。</p>
<p>请找出其中最小的元素。</p>
<p>注意数组中可能存在重复的元素。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>]</span><br><span class="line">输出: <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">0</span>,<span class="number">1</span>]</span><br><span class="line">输出: <span class="number">0</span></span><br></pre></td></tr></table></figure>


<p><strong>说明：</strong></p>
<ul>
<li>这道题是 寻找旋转排序数组中的最小值 的延伸题目。</li>
<li>允许重复会影响算法的时间复杂度吗？会如何影响，为什么？  </li>
</ul>
<p><strong>解法一</strong></p>
<blockquote>
<p>建议直接参考解法2</p>
</blockquote>
<p>相比上一题有了重复的元素，在跳转的时候需要分清楚情况，在mid和中点相等的时候只排除右边界一个元素</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findMin</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid] &gt; nums[right])&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(nums[mid] &lt; nums[right])&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right--; <span class="comment">//和右边界相等,无法判断,只缩减一步</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[left];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>(UPDATE: 2020.7.22)</p>
<p>相比<a href="#153-%E5%AF%BB%E6%89%BE%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9C%80%E5%B0%8F%E5%80%BC">寻找旋转排序数组中的最小值</a>，仅仅只是加了一个尾部去重的操作，去重后就和上面的情况一样了，这样就比前面的解法更加清晰了，时间复杂度也还是一样的</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="comment"># update: 2020/4/8</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">findMin</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>]</span>) -&gt; <span class="built_in">int</span>:</span></span><br><span class="line">        left, right = <span class="number">0</span>, <span class="built_in">len</span>(nums)-<span class="number">1</span></span><br><span class="line">        res = <span class="number">0</span></span><br><span class="line">        <span class="keyword">while</span> right &gt;= <span class="number">0</span> <span class="keyword">and</span> nums[right] == nums[<span class="number">0</span>]:</span><br><span class="line">            right -= <span class="number">1</span></span><br><span class="line">        nr = right</span><br><span class="line">        <span class="keyword">while</span> left &lt;= right:</span><br><span class="line">            mid = left + (right - left)//<span class="number">2</span></span><br><span class="line">            <span class="comment"># 和nr比，不能和0比，可能会有0 1 2这样的</span></span><br><span class="line">            <span class="keyword">if</span> nums[mid] &gt; nums[nr]:</span><br><span class="line">                left = mid + <span class="number">1</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                res = mid</span><br><span class="line">                right = mid - <span class="number">1</span></span><br><span class="line">        <span class="keyword">return</span> nums[res]</span><br></pre></td></tr></table></figure>

<h2 id="33-搜索旋转排序数组"><a href="#33-搜索旋转排序数组" class="headerlink" title="33. 搜索旋转排序数组"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array/" >33. 搜索旋转排序数组<i class="fas fa-external-link-alt"></i></a></h2><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。</p>
<p>( 例如，数组 <code>[0,1,2,4,5,6,7]</code> 可能变为 <code>[4,5,6,7,0,1,2]</code> )。</p>
<p>搜索一个给定的目标值，如果数组中存在这个目标值，则返回它的索引，否则返回 <code>-1</code> 。</p>
<p>你可以假设数组中不存在重复的元素。</p>
<p>你的算法时间复杂度必须是 <em>O</em>(log <em>n</em>) 级别。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>], target = <span class="number">0</span></span><br><span class="line">输出: <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>], target = <span class="number">3</span></span><br><span class="line">输出: -<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>题目明确要求了时间复杂度O(logn)，所以肯定还是要二分，先上代码吧</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">search2</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len = nums.length;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> ((nums == <span class="keyword">null</span>) || (len &lt;= <span class="number">0</span>)) &#123;</span><br><span class="line">        <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">int</span> lo = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> hi = len - <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (lo &lt;= hi) &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = lo + ((hi - lo) / <span class="number">2</span>);</span><br><span class="line">        <span class="comment">// 左, 右 指的是旋转点左右</span></span><br><span class="line">        <span class="keyword">if</span> (nums[mid] &gt; target) &#123; <span class="comment">//首先是大于target的情况</span></span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (target &lt; nums[lo]) &#123;</span><br><span class="line">                <span class="comment">//target在右边</span></span><br><span class="line">                <span class="comment">//mid未知还需要判断下 画一个折线图就很清楚了</span></span><br><span class="line">                <span class="keyword">if</span> (nums[mid] &lt;= nums[hi]) &#123; <span class="comment">//mid也在右边</span></span><br><span class="line">                    hi = mid - <span class="number">1</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    <span class="comment">//mid在左边</span></span><br><span class="line">                    lo = mid + <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (target &gt; nums[lo]) &#123;</span><br><span class="line">                <span class="comment">//说明mid在左边, target也在左边</span></span><br><span class="line">                hi = mid - <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> lo;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span> (nums[mid] &lt; target) &#123; <span class="comment">//小于target的情况</span></span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (target &lt; nums[hi]) &#123;</span><br><span class="line">                <span class="comment">//mid在右边，target在右边</span></span><br><span class="line">                lo = mid + <span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">if</span> (target &gt; nums[hi]) &#123;</span><br><span class="line">                <span class="comment">//target在左边</span></span><br><span class="line">                <span class="comment">//mid未知还需要判断下</span></span><br><span class="line">                <span class="keyword">if</span> (nums[mid] &gt; nums[hi]) &#123; <span class="comment">//mid在左边</span></span><br><span class="line">                    lo = mid + <span class="number">1</span>;</span><br><span class="line">                &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                    hi = mid - <span class="number">1</span>;</span><br><span class="line">                &#125;</span><br><span class="line">            &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">                <span class="keyword">return</span> hi;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            <span class="keyword">return</span> mid;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="comment">/*if(hi&gt;=0&amp;&amp;lo&lt;len&amp;&amp;nums[lo]&lt;nums[hi])&#123;</span></span><br><span class="line"><span class="comment">                   //切换成有序的二分</span></span><br><span class="line"><span class="comment">                   while(lo&lt;=hi)&#123;</span></span><br><span class="line"><span class="comment">                         mid=lo+(hi-lo)/2;</span></span><br><span class="line"><span class="comment">                         if(nums[mid]&gt;target)&#123;</span></span><br><span class="line"><span class="comment">                                    hi=mid-1;</span></span><br><span class="line"><span class="comment">                         &#125;else if(nums[mid]&lt;target)&#123;</span></span><br><span class="line"><span class="comment">                                    lo=mid+1;</span></span><br><span class="line"><span class="comment">                       &#125;else return mid;</span></span><br><span class="line"><span class="comment">                   &#125;</span></span><br><span class="line"><span class="comment">            &#125;*/</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p>1ms，99% 纯if判断<strong>target</strong>和<strong>mid</strong>的位置，然后选择移动<strong>lo</strong>还是<strong>hi</strong>，一开始我随便找了几组数然后就开始写，写到后面发现都是bug😂，这里画个图很方便</p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top///20190507/vQgFb8yle0FH.png?imageslim"
                      alt="mark"
                ></p>
<p>在里面找点会很清晰</p>
<p><strong>解法二</strong></p>
<p>当然还有一种更加简单也不用这么复杂的方法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> lo=<span class="number">0</span>,hi=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span>(nums==<span class="keyword">null</span>||nums.length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span>  -<span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> index=-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;=nums[lo])&#123;</span><br><span class="line">            <span class="comment">//左半部分有序</span></span><br><span class="line">            index=binarySearch(nums,target,lo,mid);</span><br><span class="line">            <span class="comment">//对右半部分二分</span></span><br><span class="line">            <span class="keyword">if</span>(index==-<span class="number">1</span>)&#123;</span><br><span class="line">                lo=mid+<span class="number">1</span>;</span><br><span class="line">                <span class="comment">//lo--&gt;mid 没找到就对右半部分继续划分</span></span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">return</span> index;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]&lt;nums[lo])&#123;</span><br><span class="line">            <span class="comment">//右半部分有序</span></span><br><span class="line">            index=binarySearch(nums,target,mid,hi);</span><br><span class="line">            <span class="keyword">if</span>(index==-<span class="number">1</span>)&#123;</span><br><span class="line">                hi=mid-<span class="number">1</span>;</span><br><span class="line">            &#125; <span class="keyword">else</span> <span class="keyword">return</span> index;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>  index;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">binarySearch</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;target)&#123;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125; <span class="keyword">else</span> <span class="keyword">return</span> mid;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这个应该比上一个慢一点，最好情况下是<code>O(logN)</code>直接将<strong>target</strong>划分到有序的那一边，如果没划分到有序的那一边就会花费时间去二分尝试切割数组，时间复杂度应该是<code>logN+log(N/2)+log(N/4)+...log(N/N)</code> 最后整体复杂度应该是<code>O(logN*logN)</code> ，虽然比 <code>logN</code> 好很多，但是并不是我们想要的算法</p>
<p><strong>解法三</strong></p>
<p>相当巧妙的解法！参考 <a class="link"   target="_blank" rel="noopener" href="https://leetcode.com/problems/search-in-rotated-sorted-array/discuss/14435/Clever-idea-making-it-simple" >lcus<i class="fas fa-external-link-alt"></i></a>，通过判断 <code>target</code>和<code>mid</code>的位置，如果<code>target</code>和<code>mid</code>不在同一段就将 <code>【4，5，6，7，0，1，2】 </code>转换成 <code>【4，5，6，7，INT_MAX，INT_MAX，INT_MAX】</code>或者<code>【INT_MIN，INT_MIN，INT_MIN，INT_MIN，0，1，2】</code> 然后再进行二分</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span> </span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">search</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">            <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">            <span class="comment">//这一步 (nums[mid]&gt;=nums[0])==(target&gt;=nums[0]) 很巧秒，其实用异或也可以</span></span><br><span class="line">            <span class="keyword">int</span> midNum=(nums[mid]&gt;=nums[<span class="number">0</span>])==(target&gt;=nums[<span class="number">0</span>])?nums[mid]:</span><br><span class="line">                        nums[mid]&gt;=nums[<span class="number">0</span>]?Integer.MIN_VALUE:Integer.MAX_VALUE;</span><br><span class="line">            <span class="keyword">if</span>(midNum&lt;target)&#123;</span><br><span class="line">                left=mid+<span class="number">1</span>;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                right=mid;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> nums[left]!=target?-<span class="number">1</span>:left;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><code>(nums[mid]&gt;=nums[0])==(target&gt;=nums[0])</code> 这一步很巧妙，满足这个关系就说明mid和target在同一段，不用变化，可以直接求，否则就根据mid的位置考虑如何变化</p>
<h2 id="81-搜索旋转排序数组-II"><a href="#81-搜索旋转排序数组-II" class="headerlink" title="81. 搜索旋转排序数组 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/" >81. 搜索旋转排序数组 II<i class="fas fa-external-link-alt"></i></a></h2><p>假设按照升序排序的数组在预先未知的某个点上进行了旋转。</p>
<p>( 例如，数组 <code>[0,0,1,2,2,5,6]</code> 可能变为 <code>[2,5,6,0,0,1,2]</code> )。</p>
<p>编写一个函数来判断给定的目标值是否存在于数组中。若存在返回 <code>true</code>，否则返回 <code>false</code>。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">2</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>], target = <span class="number">0</span></span><br><span class="line">输出: <span class="literal">true</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">2</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>], target = <span class="number">3</span></span><br><span class="line">输出: <span class="literal">false</span></span><br></pre></td></tr></table></figure>

<p><strong>进阶:</strong></p>
<ul>
<li>这是 <a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-in-rotated-sorted-array/description/" >搜索旋转排序数组<i class="fas fa-external-link-alt"></i></a> 的延伸题目，本题中的 <code>nums</code>  可能包含重复元素。</li>
<li>这会影响到程序的时间复杂度吗？会有怎样的影响，为什么？</li>
</ul>
<p><strong>解法一</strong></p>
<p>WA哭了，好难搞，要是在工程上我肯定直接遍历了，太细节了这波</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">search</span><span class="params">(nums []<span class="keyword">int</span>, target <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    n:=<span class="built_in">len</span>(nums)</span><br><span class="line">    <span class="keyword">if</span> n==<span class="number">0</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="literal">false</span></span><br><span class="line">    &#125;</span><br><span class="line">    left:=<span class="number">0</span></span><br><span class="line">    right:=n<span class="number">-1</span></span><br><span class="line">    <span class="keyword">for</span> left&lt;right &#123;</span><br><span class="line">        mid:=left+(right-left)/<span class="number">2</span>+<span class="number">1</span></span><br><span class="line">        <span class="keyword">if</span> nums[mid]&gt;nums[right] &#123; <span class="comment">//左半边</span></span><br><span class="line">            <span class="comment">//target在[left,mid)的有序区间内</span></span><br><span class="line">            <span class="keyword">if</span> nums[left]&lt;=target &amp;&amp; target&lt;nums[mid]&#123;</span><br><span class="line">                right=mid<span class="number">-1</span></span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                left=mid</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span> nums[mid]&lt;nums[right]&#123;</span><br><span class="line">            <span class="comment">//target在[mid,right]</span></span><br><span class="line">            <span class="keyword">if</span> nums[mid]&lt;=target &amp;&amp; target&lt;=nums[right]&#123;</span><br><span class="line">                left=mid</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                right=mid<span class="number">-1</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//mid==right看right是不是target</span></span><br><span class="line">            <span class="keyword">if</span> nums[right]==target&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="literal">true</span></span><br><span class="line">            &#125;</span><br><span class="line">            right--</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[left]==target</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>看着别人的题解写都WA了5，6次。。。。这个其实就不能按照上一题的思路来了，因为有重复的，不好判断mid和target是不是在同一边</p>
<p><strong>解法二</strong></p>
<p>（update：2020/4/8）和上面的搜索最小值一样，如果只是中间重复没有任何影响，但是如果是头尾重复，那么问题就大了，我们就没办法通过头或者尾的值，判断target和mid所在的区间，所以我们可以开始先对头尾去重，这样就可以方便判断target和mid所在区间，比如1 0 1 1 1就可以变成1 0，然后再进行二分就很简单了</p>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Solution</span>:</span></span><br><span class="line">    <span class="function"><span class="keyword">def</span> <span class="title">search</span>(<span class="params">self, nums: <span class="type">List</span>[<span class="built_in">int</span>], target: <span class="built_in">int</span></span>) -&gt; <span class="built_in">bool</span>:</span></span><br><span class="line">        left, right = <span class="number">0</span>, <span class="built_in">len</span>(nums)-<span class="number">1</span></span><br><span class="line">        res = <span class="number">0</span></span><br><span class="line">        <span class="comment"># 尾部去重，方便确定target和mid所在区间</span></span><br><span class="line">        <span class="keyword">while</span> right &gt;= <span class="number">0</span> <span class="keyword">and</span> nums[right] == nums[<span class="number">0</span>]:</span><br><span class="line">            right -= <span class="number">1</span></span><br><span class="line">        <span class="keyword">while</span> left &lt;= right:</span><br><span class="line">            mid = left + (right-left)//<span class="number">2</span></span><br><span class="line">            v = nums[mid] <span class="keyword">if</span> (nums[mid] &lt; nums[<span class="number">0</span>]) == (target &lt; nums[<span class="number">0</span>]) <span class="keyword">else</span> <span class="built_in">float</span>(<span class="string">&quot;inf&quot;</span>) <span class="keyword">if</span> nums[mid] &lt; nums[<span class="number">0</span>] <span class="keyword">else</span> <span class="built_in">float</span>(<span class="string">&quot;-inf&quot;</span>)</span><br><span class="line">            <span class="keyword">if</span> v &lt;= target:</span><br><span class="line">                res = mid</span><br><span class="line">                left = mid + <span class="number">1</span></span><br><span class="line">            <span class="keyword">else</span>:</span><br><span class="line">                right = mid - <span class="number">1</span></span><br><span class="line">        <span class="keyword">return</span> <span class="literal">True</span> <span class="keyword">if</span> nums[res] == target <span class="keyword">else</span> <span class="literal">False</span></span><br></pre></td></tr></table></figure>

<h2 id="744-寻找比目标字母大的最小字母"><a href="#744-寻找比目标字母大的最小字母" class="headerlink" title="744. 寻找比目标字母大的最小字母"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-smallest-letter-greater-than-target/" >744. 寻找比目标字母大的最小字母<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个排序后的字符列表 <code>letters</code> ，列表中只包含小写英文字母。另给出一个目标字母 <code>target</code>，请你寻找在这一有序列表里比目标字母大的最小字母。</p>
<p>在比较时，字母是依序循环出现的。举个例子：</p>
<ul>
<li>如果目标字母 <code>target = &#39;z&#39;</code> 并且字符列表为 <code>letters = [&#39;a&#39;, &#39;b&#39;]</code>，则答案返回 <code>&#39;a&#39;</code></li>
</ul>
<p><strong>示例：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;a&quot;</span></span><br><span class="line">输出: <span class="string">&quot;c&quot;</span></span><br><span class="line"></span><br><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;c&quot;</span></span><br><span class="line">输出: <span class="string">&quot;f&quot;</span></span><br><span class="line"></span><br><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;d&quot;</span></span><br><span class="line">输出: <span class="string">&quot;f&quot;</span></span><br><span class="line"></span><br><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;g&quot;</span></span><br><span class="line">输出: <span class="string">&quot;j&quot;</span></span><br><span class="line"></span><br><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;j&quot;</span></span><br><span class="line">输出: <span class="string">&quot;c&quot;</span></span><br><span class="line"></span><br><span class="line">输入:</span><br><span class="line">letters = [<span class="string">&quot;c&quot;</span>, <span class="string">&quot;f&quot;</span>, <span class="string">&quot;j&quot;</span>]</span><br><span class="line">target = <span class="string">&quot;k&quot;</span></span><br><span class="line">输出: <span class="string">&quot;c&quot;</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>letters</code>长度范围在<code>[2, 10000]</code>区间内。</li>
<li><code>letters</code> 仅由小写字母组成，最少包含两个不同的字母。</li>
<li>目标字母<code>target</code> 是一个小写字母。</li>
</ol>
<p><strong>解法一</strong></p>
<p>按照新模板写的，题解区很多人讨论<code>[&#39;z&#39;，&#39;a&#39;，&#39;b&#39;]</code>这样的case，其实我觉得没必要，纠结这没啥意义，可能还是题目描述有点问题，我们就直接当普通二分写就行了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">char</span> <span class="title">nextGreatestLetter</span><span class="params">(<span class="keyword">char</span>[] letters, <span class="keyword">char</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=letters.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>; <span class="comment">//注意找不到的情况</span></span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=(left+right)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(letters[mid]&gt;target)&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> letters[res];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="34-在排序数组中查找元素的第一个和最后一个位置"><a href="#34-在排序数组中查找元素的第一个和最后一个位置" class="headerlink" title="34. 在排序数组中查找元素的第一个和最后一个位置"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/" >34. 在排序数组中查找元素的第一个和最后一个位置<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个按照升序排列的整数数组 <code>nums</code>，和一个目标值 <code>target</code>。找出给定目标值在数组中的开始位置和结束位置。</p>
<p>你的算法时间复杂度必须是 <em>O</em>(log <em>n</em>) 级别。</p>
<p>如果数组中不存在目标值，返回 <code>[-1, -1]</code>。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">5</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">8</span>,<span class="number">10</span>], target = <span class="number">8</span></span><br><span class="line">输出: [<span class="number">3</span>,<span class="number">4</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">5</span>,<span class="number">7</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">8</span>,<span class="number">10</span>], target = <span class="number">6</span></span><br><span class="line">输出: [-<span class="number">1</span>,-<span class="number">1</span>]</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>时间复杂度O(logN)，肯定还是要二分</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//两次二分</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] searchRange(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span>(nums.length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;-<span class="number">1</span>,-<span class="number">1</span>&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;left(nums,target,<span class="number">0</span>,nums.length-<span class="number">1</span>),right(nums,target,<span class="number">0</span>,nums.length-<span class="number">1</span>)&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//5,7,7,8,8,8,8,10,10</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">left</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="comment">//System.out.println(&quot;lo: &quot;+nums[lo]+&quot;mid: &quot;+nums[mid] +&quot;hi: &quot;+nums[hi]);</span></span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]&gt;target)&#123;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(mid&gt;<span class="number">0</span>)&#123; <span class="comment">//nums[mid]=target</span></span><br><span class="line">            <span class="keyword">if</span>(nums[mid-<span class="number">1</span>]!=target)&#123;</span><br><span class="line">                <span class="keyword">return</span> mid;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//控制向左找</span></span><br><span class="line">                hi=mid-<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid; <span class="comment">//0</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">right</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;=hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123;</span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(nums[mid]&gt;target)&#123;</span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(mid&lt;nums.length-<span class="number">1</span>)&#123;</span><br><span class="line">            <span class="keyword">if</span>(nums[mid+<span class="number">1</span>]!=target)&#123;</span><br><span class="line">                <span class="keyword">return</span> mid;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="comment">//控制向右找</span></span><br><span class="line">                lo=mid+<span class="number">1</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid; <span class="comment">//nums.length</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> -<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>1ms ，99% 核心就是两次二分，分别向左和向后二分整个数组， 在相等的时候并不返回，多判断一下，左边的就控制hi向左边继续找，右边就控制lo向右边继续找，直到下一个不等于target就返回，和上面一题一样都是二分的变种</p>
<p><strong>解法二</strong></p>
<p>统一的解法，上面的做法虽然直白，但是没有通用性，这里借鉴评论区大佬 <a class="link"   target="_blank" rel="noopener" href="https://www.liwei.party/" >liweiwei1419<i class="fas fa-external-link-alt"></i></a>的<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-insert-position/solution/te-bie-hao-yong-de-er-fen-cha-fa-fa-mo-ban-python-/" >讲解<i class="fas fa-external-link-alt"></i></a>写一个通用的解法，之前写二分一直都是凭感觉，不注意细节，有错误就debug，东改一改，西改一改，然后就过了。。。毫无章法，以后要统一写法了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//两次二分</span></span><br><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] searchRange(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span>(nums.length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;-<span class="number">1</span>,-<span class="number">1</span>&#125;;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;left(nums,target,<span class="number">0</span>,nums.length-<span class="number">1</span>),right(nums,target,<span class="number">0</span>,nums.length-<span class="number">1</span>)&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//找大于等于target的第一个元素,小于肯定不符合</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">left</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;hi)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;target)&#123; <span class="comment">//排除小于target的,剩下【lo,hi】都是大于等于的</span></span><br><span class="line">            lo=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            hi=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[hi]==target?hi:-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//找小于等于target的最后一个元素,大于肯定不符合</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">right</span><span class="params">(<span class="keyword">int</span> []nums,<span class="keyword">int</span> target,<span class="keyword">int</span> lo,<span class="keyword">int</span> hi)</span></span>&#123;</span><br><span class="line">    <span class="keyword">while</span>(lo&lt;hi)&#123;</span><br><span class="line">        <span class="comment">//选取右中值</span></span><br><span class="line">        <span class="keyword">int</span> mid=lo+(hi-lo)/<span class="number">2</span>+<span class="number">1</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;target)&#123; <span class="comment">//排除大于target,剩下[lo,hi]都是小于等于的</span></span><br><span class="line">            hi=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="comment">//根据这个判断需要选取右中值</span></span><br><span class="line">            lo=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[hi]==target?hi:-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>新模板</strong></p>
<p>新模板比较好写</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="keyword">int</span>[] searchRange(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> target) &#123;</span><br><span class="line">    <span class="keyword">if</span>(nums==<span class="keyword">null</span> || nums.length&lt;=<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;-<span class="number">1</span>,-<span class="number">1</span>&#125;;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="keyword">int</span>[]&#123;leftSearch(nums,target),rightSearch(nums,target)&#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">leftSearch</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res=right;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&gt;=target)&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>; </span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[res]==target?res:-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">rightSearch</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> target)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res=left;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]&lt;=target)&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            left=mid+<span class="number">1</span>; </span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> nums[res]==target?res:-<span class="number">1</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="面试题53-II-0～n-1中缺失的数字"><a href="#面试题53-II-0～n-1中缺失的数字" class="headerlink" title="面试题53 - II. 0～n-1中缺失的数字"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/que-shi-de-shu-zi-lcof/" >面试题53 - II. 0～n-1中缺失的数字<i class="fas fa-external-link-alt"></i></a></h2><p>一个长度为 <del>n-1</del> n 的递增排序数组中的所有数字都是唯一的，并且每个数字都在范围<del>0～n-1</del> 0<del>n 之内。在范围<del>0～n-1</del> 0</del>n内的<del>n</del> n+1 个数字中有且只有一个数字不在该数组中，请找出这个数字。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">0</span>,<span class="number">1</span>,<span class="number">3</span>]</span><br><span class="line">输出: <span class="number">2</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">9</span>]</span><br><span class="line">输出: <span class="number">8</span></span><br></pre></td></tr></table></figure>

<p><strong>限制：</strong></p>
<p><code>1 &lt;= 数组长度 &lt;= 10000</code></p>
<p><strong>解法一</strong></p>
<p>这题的题目描述感觉有点问题我稍微改了下</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">missingNumber</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(nums[mid]==mid)&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(nums[left]==left) <span class="keyword">return</span> left+<span class="number">1</span>; <span class="comment">//只有一个数</span></span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>二分找那个索引不对的元素就ok了，按照模板写的，排除法，排除相等的，最后返回的索引<code>left</code>就是缺失的数字</p>
<h2 id="852-山脉数组的峰顶索引"><a href="#852-山脉数组的峰顶索引" class="headerlink" title="852. 山脉数组的峰顶索引"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/" >852. 山脉数组的峰顶索引<i class="fas fa-external-link-alt"></i></a></h2><p>我们把符合下列属性的数组 A 称作山脉：</p>
<ul>
<li>A.length &gt;= 3</li>
<li>存在 0 &lt; i &lt; A.length - 1 使得A[0] &lt; A[1] &lt; … A[i-1] &lt; A[i] &gt; A[i+1] &gt; … &gt; A[A.length - 1]</li>
</ul>
<p>给定一个确定为山脉的数组，返回任何满足 <code>A[0] &lt; A[1] &lt; ... A[i-1] &lt; A[i] &gt; A[i+1] &gt; ... &gt; A[A.length - 1]</code> 的 i 的值。</p>
<p> <strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：[<span class="number">0</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">0</span>]</span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>其实还是上面的模板，只不过做了一点点改动而已，很傻逼的WA了一发，我也是服了自己了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">peakIndexInMountainArray</span><span class="params">(<span class="keyword">int</span>[] A)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=A.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="comment">//System.out.println(mid);</span></span><br><span class="line">        <span class="keyword">if</span> (mid&gt;<span class="number">0</span> &amp;&amp; mid&lt;A.length &amp;&amp; A[mid] &gt; A[mid-<span class="number">1</span>] &amp;&amp; A[mid]&lt;A[mid+<span class="number">1</span>]) &#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span> (mid&gt;<span class="number">0</span> &amp;&amp; mid&lt;A.length &amp;&amp; A[mid]&lt; A[mid-<span class="number">1</span>] &amp;&amp; A[mid]&gt;A[mid+<span class="number">1</span>])&#123;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            <span class="keyword">return</span> mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>代码优化 <code>2020.4.9</code> 不知道为啥之前写成哪个鬼样子。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">int</span> <span class="title">peakIndexInMountainArray</span><span class="params">(<span class="keyword">int</span>[] A)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=A.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (A[mid]&lt;A[mid+<span class="number">1</span>]) &#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1095-山脉数组中查找目标值"><a href="#1095-山脉数组中查找目标值" class="headerlink" title="1095. 山脉数组中查找目标值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-in-mountain-array/" >1095. 山脉数组中查找目标值<i class="fas fa-external-link-alt"></i></a></h2><p>（这是一个 <strong>交互式问题</strong> ）</p>
<p>给你一个 <strong>山脉数组</strong> <code>mountainArr</code>，请你返回能够使得 <code>mountainArr.get(index)</code> <strong>等于</strong> <code>target</code> <strong>最小</strong> 的下标 <code>index</code> 值。</p>
<p>如果不存在这样的下标 <code>index</code>，就请返回 <code>-1</code>。</p>
<p>何为山脉数组？如果数组 <code>A</code> 是一个山脉数组的话，那它满足如下条件：</p>
<p><strong>首先</strong>，<code>A.length &gt;= 3</code></p>
<p><strong>其次</strong>，在 <code>0 &lt; i &lt; A.length - 1</code> 条件下，存在 <code>i</code> 使得：</p>
<ul>
<li><code>A[0] &lt; A[1] &lt; ... A[i-1] &lt; A[i]</code></li>
<li><code>A[i] &gt; A[i+1] &gt; ... &gt; A[A.length - 1]</code></li>
</ul>
<p>你将 <strong>不能直接访问该山脉数组</strong>，必须通过 <code>MountainArray</code> 接口来获取数据：</p>
<ul>
<li><code>MountainArray.get(k)</code> - 会返回数组中索引为<code>k</code> 的元素（下标从 0 开始）</li>
<li><code>MountainArray.length()</code> - 会返回该数组的长度</li>
</ul>
<p><strong>注意：</strong></p>
<p>对 <code>MountainArray.get</code> 发起超过 <code>100</code> 次调用的提交将被视为错误答案。此外，任何试图规避判题系统的解决方案都将会导致比赛资格被取消。</p>
<p>为了帮助大家更好地理解交互式问题，我们准备了一个样例 “<strong>答案</strong>”：<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/playground/RKhe3ave" >https://leetcode-cn.com/playground/RKhe3ave<i class="fas fa-external-link-alt"></i></a>，请注意这 <strong>不是一个正确答案</strong>。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：array = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">3</span>,<span class="number">1</span>], target = <span class="number">3</span></span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：<span class="number">3</span> 在数组中出现了两次，下标分别为 <span class="number">2</span> 和 <span class="number">5</span>，我们返回最小的下标 <span class="number">2</span>。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：array = [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">1</span>], target = <span class="number">3</span></span><br><span class="line">输出：-<span class="number">1</span></span><br><span class="line">解释：<span class="number">3</span> 在数组中没有出现，返回 -<span class="number">1</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>3 &lt;= mountain_arr.length() &lt;= 10000</code></li>
<li><code>0 &lt;= target &lt;= 10^9</code></li>
<li><code>0 &lt;= mountain_arr.get(index) &lt;= 10^9</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>这题，，，咋说呢，数据太弱了，配不上hard题，顶多算个mid偏简单，数据大的时候可以考虑加上缓存，这样就比较有意思了，这里我就懒得加了😁</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findInMountainArray</span><span class="params">(target <span class="keyword">int</span>, mountainArr *MountainArray)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    n := mountainArr.length()</span><br><span class="line">    <span class="comment">//寻找山顶</span></span><br><span class="line">    left := <span class="number">0</span></span><br><span class="line">    right := n - <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> left &lt; right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="comment">//mid+1肯定不会越界</span></span><br><span class="line">        <span class="keyword">if</span> mountainArr.get(mid) &lt; mountainArr.get(mid+<span class="number">1</span>) &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            right = mid</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    res := <span class="number">-1</span></span><br><span class="line">    res = binarySearchUp(mountainArr, target, <span class="number">0</span>, left)</span><br><span class="line">    <span class="keyword">if</span> res == <span class="number">-1</span> &#123;</span><br><span class="line">        res = binarySearchDown(mountainArr, target, left, n<span class="number">-1</span>)</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">binarySearchUp</span><span class="params">(mountainArr *MountainArray, target, left, right <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">for</span> left &lt; right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> mountainArr.get(mid) &lt; target &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            right = mid</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> mountainArr.get(left) == target &#123;</span><br><span class="line">        <span class="keyword">return</span> left</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">binarySearchDown</span><span class="params">(mountainArr *MountainArray, target, left, right <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">for</span> left &lt; right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> mountainArr.get(mid) &gt; target &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            right = mid</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> mountainArr.get(left) == target &#123;</span><br><span class="line">        <span class="keyword">return</span> left</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>这两个二分是可以合并的，懒得合了（太懒了吧你也😅）</p>
<p><strong>UPDATE: 2020.7.14</strong></p>
<p>自定义函数传递，简化代码</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findInMountainArray</span><span class="params">(target <span class="keyword">int</span>, mA *MountainArray)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> n = mA.length()</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> right = n<span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> maxIdx = right</span><br><span class="line">    <span class="keyword">for</span> left &lt;= right&#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="comment">//左中，所以mid+1不会越界</span></span><br><span class="line">        <span class="keyword">if</span> mA.get(mid) &gt; mA.get(mid+<span class="number">1</span>)&#123;</span><br><span class="line">            maxIdx = mid</span><br><span class="line">            right = mid - <span class="number">1</span> </span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    lr := search(mA, target, <span class="number">0</span>, maxIdx, <span class="function"><span class="keyword">func</span><span class="params">(i <span class="keyword">int</span>, j <span class="keyword">int</span>)</span><span class="title">bool</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> i &lt;= j</span><br><span class="line">    &#125;)</span><br><span class="line">    <span class="keyword">if</span> lr != <span class="number">-1</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> lr</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> search(mA, target, maxIdx+<span class="number">1</span>, n<span class="number">-1</span>, <span class="function"><span class="keyword">func</span><span class="params">(i <span class="keyword">int</span>, j <span class="keyword">int</span>)</span><span class="title">bool</span></span>&#123;</span><br><span class="line">        <span class="keyword">return</span> i &gt;= j</span><br><span class="line">    &#125;)</span><br><span class="line">    </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">search</span><span class="params">(mA *MountainArray, target <span class="keyword">int</span>, left <span class="keyword">int</span>, right <span class="keyword">int</span>, less <span class="keyword">func</span>(<span class="keyword">int</span>, <span class="keyword">int</span>)</span><span class="title">bool</span>) <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> res = left</span><br><span class="line">    <span class="keyword">for</span> left &lt;= right&#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> less(mA.get(mid), target)&#123;</span><br><span class="line">            res = mid</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> mA.get(res) != target&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="162-寻找峰值"><a href="#162-寻找峰值" class="headerlink" title="162. 寻找峰值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-peak-element/" >162. 寻找峰值<i class="fas fa-external-link-alt"></i></a></h2><p>峰值元素是指其值大于左右相邻值的元素。</p>
<p>给定一个输入数组 <code>nums</code>，其中 <code>nums[i] ≠ nums[i+1]</code>，找到峰值元素并返回其索引。</p>
<p>数组可能包含多个峰值，在这种情况下，返回任何一个峰值所在位置即可。</p>
<p>你可以假设 <code>nums[-1] = nums[n] = -∞</code>。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>]</span><br><span class="line">输出: <span class="number">2</span></span><br><span class="line">解释: <span class="number">3</span> 是峰值元素，你的函数应该返回其索引 <span class="number">2</span>。</span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">4</span>]</span><br><span class="line">输出: <span class="number">1</span> 或 <span class="number">5</span> </span><br><span class="line">解释: 你的函数可以返回索引 <span class="number">1</span>，其峰值元素为 <span class="number">2</span>；</span><br><span class="line">     或者返回索引 <span class="number">5</span>， 其峰值元素为 <span class="number">6</span>。</span><br></pre></td></tr></table></figure>


<p><strong>说明:</strong></p>
<p>你的解法应该是 <code>O(logN)</code> 时间复杂度的。</p>
<p><strong>解法一</strong></p>
<p>题目挑明了logN的复杂度，那么肯定就是二分了，那是怎么个二分的思路呢？题目其实也说了很清楚了，边界的左右两边都是<code>-∞</code> 所以我们直接按照递增的去搜，最后肯定能搜索到峰值</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findPeakElement</span><span class="params">(<span class="keyword">int</span>[] nums)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(<span class="comment">/*mid+1&lt;nums.length &amp;&amp;*/</span>nums[mid]&lt;nums[mid+<span class="number">1</span>])&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>liweiwei大佬的二分模板真好用！！！</p>
<h2 id="74-搜索二维矩阵"><a href="#74-搜索二维矩阵" class="headerlink" title="74. 搜索二维矩阵"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-a-2d-matrix/" >74. 搜索二维矩阵<i class="fas fa-external-link-alt"></i></a></h2><p>编写一个高效的算法来判断 <code>m x n</code> 矩阵中，是否存在一个目标值。该矩阵具有如下特性：</p>
<p>每行中的整数从左到右按升序排列。<br>每行的第一个整数大于前一行的最后一个整数。<br><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">matrix = [</span><br><span class="line">  [<span class="number">1</span>,   <span class="number">3</span>,  <span class="number">5</span>,  <span class="number">7</span>],</span><br><span class="line">  [<span class="number">10</span>, <span class="number">11</span>, <span class="number">16</span>, <span class="number">20</span>],</span><br><span class="line">  [<span class="number">23</span>, <span class="number">30</span>, <span class="number">34</span>, <span class="number">50</span>]</span><br><span class="line">]</span><br><span class="line">target = <span class="number">3</span></span><br><span class="line">输出: <span class="keyword">true</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">matrix = [</span><br><span class="line">  [<span class="number">1</span>,   <span class="number">3</span>,  <span class="number">5</span>,  <span class="number">7</span>],</span><br><span class="line">  [<span class="number">10</span>, <span class="number">11</span>, <span class="number">16</span>, <span class="number">20</span>],</span><br><span class="line">  [<span class="number">23</span>, <span class="number">30</span>, <span class="number">34</span>, <span class="number">50</span>]</span><br><span class="line">]</span><br><span class="line">target = <span class="number">13</span></span><br><span class="line">输出: <span class="keyword">false</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">searchMatrix</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(matrix==<span class="keyword">null</span> || matrix.length&lt;=<span class="number">0</span> || matrix[<span class="number">0</span>].length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> m=matrix.length;</span><br><span class="line">    <span class="keyword">int</span> n=matrix[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span> low=<span class="number">0</span>,high=m-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (target&gt;matrix[m-<span class="number">1</span>][n-<span class="number">1</span>] || target &lt; matrix[<span class="number">0</span>][<span class="number">0</span>]) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">while</span>(low&lt;=high)&#123; <span class="comment">//二分确定在哪一行</span></span><br><span class="line">        <span class="keyword">int</span> mid=low+(high-low)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (target == matrix[mid][<span class="number">0</span>]) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(matrix[mid][<span class="number">0</span>]&lt;target)&#123;</span><br><span class="line">            low=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            high=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> column=low!=<span class="number">0</span>?low-<span class="number">1</span>:low;</span><br><span class="line">    low=<span class="number">0</span>;</span><br><span class="line">    high=n-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(low&lt;high)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=low+(high-low)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (matrix[column][mid]==target) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span>(matrix[column][mid] &lt; target)&#123;</span><br><span class="line">            low=mid+<span class="number">1</span>; </span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            high=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> target==matrix[column][low];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>😔，这题wa了11次，是的，11次，可想而知我有多彩，最后写出来的解法还是如此的难看，主要就是在确定在哪一行的时候写出了好多问题，可以看到我上下的两种二分方法是不一样的，前期就揪着一种写，按照上面的板子写，结果写出了一堆bug… 以后写二分还是要注意啊，1s确定思路，代码写了3h。。。。</p>
<p><strong>解法二</strong></p>
<p>看了评论区写出来的，利用取模和除将二维数组拉成一维的，相当的优秀，也不用考虑那些边界，时间复杂度和上面一样<code>log(nm)</code> </p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">searchMatrix</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(matrix==<span class="keyword">null</span> || matrix.length&lt;=<span class="number">0</span> || matrix[<span class="number">0</span>].length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> m=matrix.length;</span><br><span class="line">    <span class="keyword">int</span> n=matrix[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=m*n-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(matrix[mid/n][mid%n]&lt;target)&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> matrix[left/n][left%n]==target;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="240-搜索二维矩阵-II"><a href="#240-搜索二维矩阵-II" class="headerlink" title="240. 搜索二维矩阵 II"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-a-2d-matrix-ii/" >240. 搜索二维矩阵 II<i class="fas fa-external-link-alt"></i></a></h2><p>编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性：</p>
<ul>
<li>每行的元素从左到右升序排列。</li>
<li>每列的元素从上到下升序排列。</li>
</ul>
<p><strong>示例:</strong><br>现有矩阵 matrix 如下：</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">[</span><br><span class="line">  [<span class="number">1</span>,   <span class="number">4</span>,  <span class="number">7</span>, <span class="number">11</span>, <span class="number">15</span>],</span><br><span class="line">  [<span class="number">2</span>,   <span class="number">5</span>,  <span class="number">8</span>, <span class="number">12</span>, <span class="number">19</span>],</span><br><span class="line">  [<span class="number">3</span>,   <span class="number">6</span>,  <span class="number">9</span>, <span class="number">16</span>, <span class="number">22</span>],</span><br><span class="line">  [<span class="number">10</span>, <span class="number">13</span>, <span class="number">14</span>, <span class="number">17</span>, <span class="number">24</span>],</span><br><span class="line">  [<span class="number">18</span>, <span class="number">21</span>, <span class="number">23</span>, <span class="number">26</span>, <span class="number">30</span>]</span><br><span class="line">]</span><br></pre></td></tr></table></figure>

<p>给定 target = <code>5</code>，返回 <code>true</code>。</p>
<p>给定 target = <code>20</code>，返回 <code>false</code>。</p>
<p><strong>解法一</strong></p>
<p>看上一题 <a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/search-a-2d-matrix/" >240. 搜索二维矩阵<i class="fas fa-external-link-alt"></i></a>  的评论区的时候看到了这种解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">searchMatrix</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(matrix==<span class="keyword">null</span> || matrix.length&lt;=<span class="number">0</span> || matrix[<span class="number">0</span>].length&lt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> m=matrix.length;</span><br><span class="line">    <span class="keyword">int</span> n=matrix[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span>  column=<span class="number">0</span>,row=m-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(column&lt;n &amp;&amp; row&gt;=<span class="number">0</span>)&#123;</span><br><span class="line">        <span class="comment">//System.out.println(row+&quot;,&quot;+column);</span></span><br><span class="line">        <span class="keyword">if</span> (matrix[row][column]==target) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (matrix[row][column] &gt; target) &#123;</span><br><span class="line">            row--;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            column++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>整个矩阵从左上到右下，其实就分为了两块，每个元素的左上一定小于当前元素，右下一定大于当前元素，这题也可以二分，就像下面的<a href="#1351-%E7%BB%9F%E8%AE%A1%E6%9C%89%E5%BA%8F%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%9A%84%E8%B4%9F%E6%95%B0">1351. 统计有序矩阵中的负数</a>一样，但是时间复杂度会高一些</p>
<h2 id="1351-统计有序矩阵中的负数"><a href="#1351-统计有序矩阵中的负数" class="headerlink" title="1351. 统计有序矩阵中的负数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/count-negative-numbers-in-a-sorted-matrix/" >1351. 统计有序矩阵中的负数<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>给你一个 <code>m * n</code> 的矩阵 <code>grid</code>，矩阵中的元素无论是按行还是按列，都以非递增顺序排列。 </p>
<p>请你统计并返回 <code>grid</code> 中 <strong>负数</strong> 的数目。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">-1</span>],[<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">-1</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">-1</span>,<span class="number">-2</span>],[<span class="number">-1</span>,<span class="number">-1</span>,<span class="number">-2</span>,<span class="number">-3</span>]]</span><br><span class="line">输出：<span class="number">8</span></span><br><span class="line">解释：矩阵中共有 <span class="number">8</span> 个负数。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">3</span>,<span class="number">2</span>],[<span class="number">1</span>,<span class="number">0</span>]]</span><br><span class="line">输出：<span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">1</span>,<span class="number">-1</span>],[<span class="number">-1</span>,<span class="number">-1</span>]]</span><br><span class="line">输出：<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：grid = [[<span class="number">-1</span>]]</span><br><span class="line">输出：<span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>m == grid.length</code></li>
<li>  <code>n == grid[i].length</code></li>
<li>  <code>1 &lt;= m, n &lt;= 100</code></li>
<li>  <code>-100 &lt;= grid[i][j] &lt;= 100</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>没啥好说的，和上面的解法一样，从左下角向上搜索</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">countNegatives</span><span class="params">(grid [][]<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(grid) &lt;= <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> m, n = <span class="built_in">len</span>(grid), <span class="built_in">len</span>(grid[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> i, j = m<span class="number">-1</span>, <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> i &gt;= <span class="number">0</span> &amp;&amp; j &lt; n &#123;</span><br><span class="line">        <span class="keyword">if</span> grid[i][j] &lt; <span class="number">0</span> &#123;</span><br><span class="line">            count += n - j</span><br><span class="line">            i--</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            j++</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>O(mlogn)解法</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//O(mlogn) 只利用了行逆序的条件</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">countNegatives</span><span class="params">(grid [][]<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="built_in">len</span>(grid) &lt;= <span class="number">0</span> &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> m = <span class="built_in">len</span>(grid)</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(grid[<span class="number">0</span>])</span><br><span class="line">    <span class="keyword">for</span> i := <span class="number">0</span>; i &lt; m; i++ &#123;</span><br><span class="line">        count += (n - search(grid[i]))</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">search</span><span class="params">(nums []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> right = <span class="built_in">len</span>(nums)<span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> res = right+<span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> nums[mid] &lt; <span class="number">0</span> &#123;</span><br><span class="line">            res = mid</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="4-寻找两个有序数组的中位数"><a href="#4-寻找两个有序数组的中位数" class="headerlink" title="4. 寻找两个有序数组的中位数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/median-of-two-sorted-arrays/" >4. 寻找两个有序数组的中位数<i class="fas fa-external-link-alt"></i></a></h2><p>给定两个大小为 m 和 n 的有序数组 <code>nums1</code> 和 <code>nums2</code>。</p>
<p>请你找出这两个有序数组的中位数，并且要求算法的时间复杂度为 <code>O(log(m + n))</code>。</p>
<p>你可以假设 <code>nums1</code> 和 <code>nums2</code> 不会同时为空。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">nums1 = [<span class="number">1</span>, <span class="number">3</span>]</span><br><span class="line">nums2 = [<span class="number">2</span>]</span><br><span class="line"></span><br><span class="line">则中位数是 <span class="number">2.0</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">nums1 = [<span class="number">1</span>, <span class="number">2</span>]</span><br><span class="line">nums2 = [<span class="number">3</span>, <span class="number">4</span>]</span><br><span class="line"></span><br><span class="line">则中位数是 (<span class="number">2</span> + <span class="number">3</span>)/<span class="number">2</span> = <span class="number">2.5</span></span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>Hard题，首先想到的是归并，但是时间复杂度不符合要求，最低要求 <code>O(log(m+n))</code>，想了好一会儿实在是想不出来（菜）然后看了评论区的解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//find nums1+nums2 /2 大的数</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">findMedianSortedArrays</span><span class="params">(<span class="keyword">int</span>[] nums1, <span class="keyword">int</span>[] nums2)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> m=nums1.length;</span><br><span class="line">    <span class="keyword">int</span> n=nums2.length;</span><br><span class="line">    <span class="keyword">int</span> leftMid=(m+n+<span class="number">1</span>)/<span class="number">2</span>;</span><br><span class="line">    <span class="keyword">int</span> rightMid=(m+n+<span class="number">2</span>)/<span class="number">2</span>;</span><br><span class="line">    <span class="keyword">return</span> (findMedian(nums1,<span class="number">0</span>,m-<span class="number">1</span>,nums2,<span class="number">0</span>,n-<span class="number">1</span>,leftMid) + findMedian(nums1,<span class="number">0</span>,m-<span class="number">1</span>,nums2,<span class="number">0</span>,n-<span class="number">1</span>,rightMid)) * <span class="number">0.5</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//    i</span></span><br><span class="line"><span class="comment">//1 2 3 5</span></span><br><span class="line"><span class="comment">//    j</span></span><br><span class="line"><span class="comment">//1 2 4 6 7 8 9     k=6 find k/2=3</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">//        i</span></span><br><span class="line"><span class="comment">//*1 2 3* 5</span></span><br><span class="line"><span class="comment">//  j  </span></span><br><span class="line"><span class="comment">//1 2 4 6 7 8 9     k=3 find k/2=1  res=4</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">findMedian</span><span class="params">(<span class="keyword">int</span>[] nums1,<span class="keyword">int</span> left1,<span class="keyword">int</span> right1, <span class="keyword">int</span>[] nums2,<span class="keyword">int</span> left2,<span class="keyword">int</span> right2,<span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> len1=right1-left1+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> len2=right2-left2+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (len1==<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> nums2[left2+k-<span class="number">1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (len2==<span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> nums1[left1+k-<span class="number">1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (k==<span class="number">1</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> Math.min(nums1[left1],nums2[left2]);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> i=left1+Math.min(len1,k/<span class="number">2</span>)-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> j=left2+Math.min(len2,k/<span class="number">2</span>)-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">if</span> (nums1[i] &lt; nums2[j]) &#123;</span><br><span class="line">        <span class="keyword">return</span> findMedian(nums1,i+<span class="number">1</span>,right1,nums2,left2,right2,k-(i-left1+<span class="number">1</span>));</span><br><span class="line">    &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> findMedian(nums1,left1,right1,nums2,j+<span class="number">1</span>,right2,k-(j-left2+<span class="number">1</span>));</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种解法还是挺妙的，求第k小的思路，两个数组都是有序的，我们要求第k小，我们可以将k一分为二，看看两个数组的 <code>k/2</code> 位置的元素哪个大哪个小，小的哪个数组前 <code>k/2</code> 个元素就可以直接排除掉，因为他们必不可能是第k小的元素，举个例子就很容易理解</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">5</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">4</span> <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span>  k=<span class="number">6</span></span><br><span class="line">k/<span class="number">2</span>=<span class="number">3</span>,分别在两数组中找第三个元素，也即是<span class="number">3</span>，<span class="number">4</span>明显<span class="number">3</span>比较小，所以我们可以直接排除第一个数组的<span class="number">1</span>，<span class="number">2</span>，<span class="number">3</span>三个元素，他们必不可能是第k小的元素！</span><br><span class="line">*<span class="number">1</span> <span class="number">2</span> <span class="number">3</span>* <span class="number">5</span></span><br><span class="line"><span class="number">1</span> <span class="number">2</span> <span class="number">4</span> <span class="number">6</span> <span class="number">7</span> <span class="number">8</span> <span class="number">9</span>  k=<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p>然后重复上面的过程，每次排除<code>k/2</code> 的元素，最后在<code>log(k)</code> 的时间复杂度下就能找到两个数组的mid，而这里<code>k=(m+n+1)/2</code> 所以是符合题目要求的，除此之外，我们还需要考虑奇数和偶数的情况，那我们就可以分别计算一下，我们求一下左中位数和右中位数，如果是奇数左中和右中就是同一个<code>(k)/2==(k+1)/2</code> ，偶数的话就是<code>(k)/2</code>和<code>(k+1)/2</code>分别就是左中和右中，然后我们直接/2就得到了解</p>
<h2 id="658-找到-K-个最接近的元素"><a href="#658-找到-K-个最接近的元素" class="headerlink" title="658. 找到 K 个最接近的元素"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-k-closest-elements/" >658. 找到 K 个最接近的元素<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个排序好的数组，两个整数 <code>k</code> 和 <code>x</code>，从数组中找到最靠近 <code>x</code>（两数之差最小）的 <code>k</code> 个数。返回的结果必须要是按升序排好的。如果有两个数与 <code>x</code> 的差值一样，优先选择数值较小的那个数。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>], k=<span class="number">4</span>, x=<span class="number">3</span></span><br><span class="line">输出: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>], k=<span class="number">4</span>, x=-<span class="number">1</span></span><br><span class="line">输出: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>]</span><br></pre></td></tr></table></figure>

<p><strong>说明:</strong></p>
<ol>
<li>k 的值为正数，且总是小于给定排序数组的长度。</li>
<li>数组不为空，且长度不超过 104</li>
<li>数组里的每个元素与 x 的绝对值不超过 104</li>
</ol>
<p><strong>解法一</strong></p>
<p>双指针，少点套路，多点真诚</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">findClosestElements</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> k, <span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=arr.length-<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">if</span>(Math.abs(arr[left]-x)&lt;=Math.abs(arr[right]-x))&#123;</span><br><span class="line">            right--;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left++;</span><br><span class="line">        &#125;</span><br><span class="line">        count++;</span><br><span class="line">        <span class="keyword">if</span>(count==arr.length-k) <span class="keyword">break</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=left;i&lt;=right;i++) res.add(arr[i]);</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>二分的解法，有点trick，不容易想到，参考<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-k-closest-elements/solution/pai-chu-fa-shuang-zhi-zhen-er-fen-fa-python-dai-ma/" >题解<i class="fas fa-external-link-alt"></i></a></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> List&lt;Integer&gt; <span class="title">findClosestElements</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> k, <span class="keyword">int</span> x)</span> </span>&#123;</span><br><span class="line">    <span class="comment">//左边界的取值范围</span></span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=arr.length-k;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(x-arr[mid]&gt;arr[mid+k]-x)&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    List&lt;Integer&gt; res=<span class="keyword">new</span> ArrayList&lt;&gt;();</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=left;i&lt;left+k;i++) res.add(arr[i]);</span><br><span class="line">    <span class="keyword">return</span> res;   </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="367-有效的完全平方数"><a href="#367-有效的完全平方数" class="headerlink" title="367. 有效的完全平方数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/valid-perfect-square/" >367. 有效的完全平方数<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>给定一个正整数 <em>num_，编写一个函数，如果 _num</em> 是一个完全平方数，则返回 True，否则返回 False。</p>
<p><strong>说明：</strong>不要使用任何内置的库函数，如  <code>sqrt</code>。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：<span class="number">16</span></span><br><span class="line">输出：True</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：<span class="number">14</span></span><br><span class="line">输出：False</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>二分</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">isPerfectSquare</span><span class="params">(num <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> right = num</span><br><span class="line">    <span class="keyword">var</span> res = num + <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> mid*mid &gt;= num &#123;</span><br><span class="line">            res = mid</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res*res == num</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>完全平方数的性质</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="comment">//完全平方数性质 n^2 = 1 + 3 + 5 +...+2n+1 (前n个奇数的和)</span></span><br><span class="line"><span class="comment">//所以只需要判断num能不能被奇数减成0就行了</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">isPerfectSquare</span><span class="params">(num <span class="keyword">int</span>)</span> <span class="title">bool</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> i = <span class="number">1</span></span><br><span class="line">    <span class="keyword">for</span> num &gt; <span class="number">0</span> &#123;</span><br><span class="line">        num -= i</span><br><span class="line">        i += <span class="number">2</span></span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> num == <span class="number">0</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="475-供暖器"><a href="#475-供暖器" class="headerlink" title="475. 供暖器"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/heaters/" >475. 供暖器<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。</p>
<p>现在，给出位于一条水平线上的房屋和供暖器的位置，找到可以覆盖所有房屋的最小加热半径。</p>
<p>所以，你的输入将会是房屋和供暖器的位置。你将输出供暖器的最小加热半径。</p>
<p><strong>说明:</strong></p>
<ol>
<li> 给出的房屋和供暖器的数目是非负数且不会超过 25000。</li>
<li> 给出的房屋和供暖器的位置均是非负数且不会超过10^9。</li>
<li> 只要房屋位于供暖器的半径内(包括在边缘上)，它就可以得到供暖。</li>
<li> 所有供暖器都遵循你的半径标准，加热的半径也一样。</li>
</ol>
<p><strong>示例 1:</strong></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>],[<span class="number">2</span>]</span><br><span class="line">输出: <span class="number">1</span></span><br><span class="line">解释: 仅在位置<span class="number">2</span>上有一个供暖器。如果我们将加热半径设为<span class="number">1</span>，那么所有房屋就都能得到供暖。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>],[<span class="number">1</span>,<span class="number">4</span>]</span><br><span class="line">输出: <span class="number">1</span></span><br><span class="line">解释: 在位置<span class="number">1</span>, <span class="number">4</span>上有两个供暖器。我们需要将加热半径设为<span class="number">1</span>，这样所有房屋就都能得到供暖。</span><br></pre></td></tr></table></figure>


<p><strong>解法一</strong></p>
<p>这个题目感觉不是easy啊，一开始想劈叉了，以为是二分答案，写了半天后来WA在一个很大的case，一直以为是溢出了，改了半天的bug没改出来。。。后来自己按照case的规律构建了一个小的case，发现也WA了，然后才意识到是方法错了, (case: [4,9] [4,8])，这个case按照二分答案的思路就是错的，二分答案是思路就是验证该半径下能否覆盖整个区间，其实也是题目理解有点问题，题目的要求是<strong>覆盖每个房子</strong>，而<strong>不是覆盖整个区间</strong>，所以只需要找到每个房子最近的供暖器就行了，然后统计这些最小值得最大值就是我们需要的半径</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findRadius</span><span class="params">(houses []<span class="keyword">int</span>, heaters []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="comment">//边界处理</span></span><br><span class="line">    heaters = <span class="built_in">append</span>(heaters, math.MaxInt32)</span><br><span class="line">    heaters = <span class="built_in">append</span>(heaters, math.MinInt32)</span><br><span class="line">    sort.Ints(heaters)</span><br><span class="line">    <span class="keyword">var</span> Min = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> b&#125;; <span class="keyword">return</span> a&#125;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, h := <span class="keyword">range</span> houses&#123;</span><br><span class="line">        left := search(heaters, h)</span><br><span class="line">        res = Max(res, Min(h-heaters[left], heaters[left+<span class="number">1</span>]-h))</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line">​</span><br><span class="line"><span class="comment">//target左边最近的一个</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">search</span><span class="params">(heaters []<span class="keyword">int</span>, target <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left, right = <span class="number">0</span>, <span class="built_in">len</span>(heaters)<span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> res = left <span class="comment">//左边没有供暖器</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> heaters[mid] &lt;= target&#123;</span><br><span class="line">            res = mid</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>另一种写法，不额外处理边界，也是一开始的写法</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findRadius</span><span class="params">(houses []<span class="keyword">int</span>, heaters []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    sort.Ints(heaters)</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(heaters)</span><br><span class="line">    <span class="keyword">var</span> Min = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> b&#125;; <span class="keyword">return</span> a&#125;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, h := <span class="keyword">range</span> houses&#123;</span><br><span class="line">        left := search(heaters, h)</span><br><span class="line">        <span class="keyword">if</span> left == <span class="number">-1</span>&#123; <span class="comment">//全部大于hourse,取最小的那个</span></span><br><span class="line">            res = Max(res, heaters[<span class="number">0</span>]-h)</span><br><span class="line">        &#125;<span class="keyword">else</span> <span class="keyword">if</span> left+<span class="number">1</span> &lt; n&#123;</span><br><span class="line">            res = Max(res, Min(h-heaters[left], heaters[left+<span class="number">1</span>]-h))</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            res = Max(res, h-heaters[left])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//target左边最近的一个</span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">search</span><span class="params">(heaters []<span class="keyword">int</span>, target <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    <span class="keyword">var</span> left, right = <span class="number">0</span>, <span class="built_in">len</span>(heaters)<span class="number">-1</span></span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">-1</span> <span class="comment">//左边没有供暖器</span></span><br><span class="line">    <span class="keyword">for</span> left &lt;= right &#123;</span><br><span class="line">        mid := left + (right-left)/<span class="number">2</span></span><br><span class="line">        <span class="keyword">if</span> heaters[mid] &lt;= target&#123;</span><br><span class="line">            res = mid</span><br><span class="line">            left = mid + <span class="number">1</span></span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = mid - <span class="number">1</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>时间复杂度细看的话应该是 <code>O(MlogM + MlogN)</code>（M，N分别代表houses和heaters的长度）</p>
<p><strong>解法二</strong></p>
<p>双指针，时间复杂度差别不大</p>
<figure class="highlight golang"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">findRadius</span><span class="params">(houses []<span class="keyword">int</span>, heaters []<span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123;</span><br><span class="line">    heaters = <span class="built_in">append</span>(heaters, math.MaxInt32)</span><br><span class="line">    heaters = <span class="built_in">append</span>(heaters, math.MinInt32)</span><br><span class="line">    sort.Ints(heaters)</span><br><span class="line">    sort.Ints(houses)</span><br><span class="line">    <span class="keyword">var</span> n = <span class="built_in">len</span>(heaters)</span><br><span class="line">    <span class="keyword">var</span> Min = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> a&#125;; <span class="keyword">return</span> b&#125;</span><br><span class="line">    <span class="keyword">var</span> Max = <span class="function"><span class="keyword">func</span> <span class="params">(a, b <span class="keyword">int</span>)</span> <span class="title">int</span></span> &#123; <span class="keyword">if</span> a &lt; b &#123;<span class="keyword">return</span> b&#125;; <span class="keyword">return</span> a&#125;</span><br><span class="line">    <span class="keyword">var</span> res = <span class="number">0</span></span><br><span class="line">    <span class="keyword">var</span> left = <span class="number">0</span></span><br><span class="line">    <span class="keyword">for</span> _, h := <span class="keyword">range</span> houses &#123;</span><br><span class="line">        <span class="keyword">for</span> left &lt; n &amp;&amp; heaters[left] &lt; h &#123;</span><br><span class="line">            left++</span><br><span class="line">        &#125;</span><br><span class="line">        res = Max(res, Min(heaters[left]-h, h-heaters[left<span class="number">-1</span>]))</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>时间复杂度细看的话应该是 <code>O(NlogN + MlogM + N + M)</code>（M，N分别代表houses和heaters的长度），差别不大，不过很明显双指针的好写很多</p>
<h2 id="二分答案"><a href="#二分答案" class="headerlink" title="二分答案"></a><em>二分答案</em></h2><h2 id="1283-使结果不超过阈值的最小除数"><a href="#1283-使结果不超过阈值的最小除数" class="headerlink" title="1283. 使结果不超过阈值的最小除数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-the-smallest-divisor-given-a-threshold/" >1283. 使结果不超过阈值的最小除数<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个整数数组 <code>nums</code> 和一个正整数 <code>threshold</code>  ，你需要选择一个正整数作为除数，然后将数组里每个数都除以它，并对除法结果求和。</p>
<p>请你找出能够使上述结果小于等于阈值 <code>threshold</code> 的除数中 最小 的那个。</p>
<p>每个数除以除数后都向上取整，比方说 7/3 = 3 ， 10/2 = 5 。</p>
<p>题目保证一定有解。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">9</span>], threshold = <span class="number">6</span></span><br><span class="line">输出：<span class="number">5</span></span><br><span class="line">解释：如果除数为 <span class="number">1</span> ，我们可以得到和为 <span class="number">17</span> （<span class="number">1</span>+<span class="number">2</span>+<span class="number">5</span>+<span class="number">9</span>）。</span><br><span class="line">如果除数为 <span class="number">4</span> ，我们可以得到和为 <span class="number">7</span> (<span class="number">1</span>+<span class="number">1</span>+<span class="number">2</span>+<span class="number">3</span>) 。如果除数为 <span class="number">5</span> ，和为 <span class="number">5</span> (<span class="number">1</span>+<span class="number">1</span>+<span class="number">1</span>+<span class="number">2</span>)。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">11</span>], threshold = <span class="number">11</span></span><br><span class="line">输出：<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：nums = [<span class="number">19</span>], threshold = <span class="number">5</span></span><br><span class="line">输出：<span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= nums.length &lt;= 5 * 10^4</code></li>
<li><code>1 &lt;= nums[i] &lt;= 10^6</code></li>
<li><code>nums.length &lt;= threshold &lt;= 10^6</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>周赛的题，太蠢了，没做出来。。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">smallestDivisor</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> threshold)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=<span class="number">1000000</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">            sum+=(nums[i]+mid-<span class="number">1</span>)/mid; <span class="comment">//向上取整</span></span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span> (sum&gt;threshold) &#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>其实只要明确一点这题就很容易想到二分，解空间为：<code>[1，max(nums[i])]</code> 我们只需要在这个区间之内做二分搜索就ok了，再然后就是向上取整的一个小技巧</p>
<h2 id="287-寻找重复数"><a href="#287-寻找重复数" class="headerlink" title="287. 寻找重复数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/find-the-duplicate-number/" >287. 寻找重复数<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个包含 n + 1 个整数的数组 <code>nums</code>，其数字都在 1 到 n 之间（包括 1 和 n），可知至少存在一个重复的整数。假设只有一个重复的整数，找出这个重复的数。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">1</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="number">2</span></span><br></pre></td></tr></table></figure>


<p><strong>示例 2:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: [<span class="number">3</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>]</span><br><span class="line">输出: <span class="number">3</span></span><br></pre></td></tr></table></figure>


<p><strong>说明：</strong></p>
<ul>
<li>不能更改原数组（假设数组是只读的）。</li>
<li>只能使用额外的 O(1) 的空间。</li>
<li>时间复杂度小于 O(n2) 。</li>
<li>数组中只有一个重复的数字，但它可能不止重复出现一次 </li>
</ul>
<p><strong>解法一</strong></p>
<p>这题还是挺有意思的，题目要求了数组nums是只读的，且不能使用额外的空间，且时间复杂度还要小于O(N^2)，否则的话其实可以排序，或者使用Hash表来做，这里我们使用二分来做</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//update: 2020.5.26 其实也属于二分答案</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findDuplicate</span><span class="params">(<span class="keyword">int</span>[] nums)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=nums.length-<span class="number">1</span>;</span><br><span class="line">    <span class="comment">//这里实际上是对【1,2,3,4,...n-1】这个区间进行二分</span></span><br><span class="line">    <span class="comment">//在过程中对mid检测每个数在nums数组中出现的次数</span></span><br><span class="line">    <span class="comment">//1 3 4 2 2实际上是对【1,2,3,4】区间进行二分</span></span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>+<span class="number">1</span>;</span><br><span class="line">        <span class="comment">//小于mid的数大于mid,排除mid</span></span><br><span class="line">        <span class="keyword">if</span>(count(nums,mid)&gt;=mid)&#123; </span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//n-1个整数 , 1~n有n个数     </span></span><br><span class="line"><span class="comment">//1 2 2 3 4     1~4之间, 1 2 3 4</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">count</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">int</span> n)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;nums.length;i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (nums[i]&lt;n) &#123;</span><br><span class="line">            res++;          </span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这样的解法还是很巧妙的，对nums数组的<strong>取值范围</strong>进行二分，二分的核心就是，nums数组中，小于取值范围中mid的元素应该小于等于mid</p>
<p>举个例子：<code>[1 3 4 2 2]</code> 取值范围是<code>[1 2 3 4]</code> ，取中点2，正常情况下nums中小于等于2的元素，应该最多有2个，也就是<code>[1 2]</code>2个，但是这里在nums中，有3个<code>[1 2 2]</code> 大于2了，这就说明一定有重复的元素，而且一定是小于中点2的，也就是在左半边，下一步就应该舍弃右半边，在<code>[1,2]</code>中继续查找 </p>
<p>这里按照我们之前的模板来写，先找排除mid的条件，<strong>在nums中小于mid的元素的数量小于等于mid的时候，包括mid在内的右边界都会被排除，肯定都不是重复的元素</strong> ，然后就按照模板写出二分就行了</p>
<p><strong>解法二</strong></p>
<p>快慢指针的做法，技巧性很强，一般人第一次做是很难想到这种做法的，其实和 <a href="http://imlgw.top/2019/02/27/leetcode-lian-biao-tag/#141-%E7%8E%AF%E5%BD%A2%E9%93%BE%E8%A1%A8">链表专题</a> 中的环形链表是一样的做法，然后按照那个思路走就行了，不清楚原理可以看看上面环形链表的解法</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findDuplicate</span><span class="params">(<span class="keyword">int</span>[] nums)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> slow=<span class="number">0</span>,fast=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">boolean</span> isMeet=<span class="keyword">false</span>;</span><br><span class="line">    <span class="keyword">while</span>(<span class="keyword">true</span>)&#123;</span><br><span class="line">        fast=isMeet?nums[fast]:nums[nums[fast]];</span><br><span class="line">        slow=nums[slow];</span><br><span class="line">        <span class="keyword">if</span> (fast==slow) &#123;</span><br><span class="line">            <span class="keyword">if</span> (isMeet) &#123;</span><br><span class="line">                <span class="keyword">return</span> slow;</span><br><span class="line">            &#125;</span><br><span class="line">            fast=<span class="number">0</span>;</span><br><span class="line">            isMeet=<span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种解法的关键是将数组值看作索引然后再数组像链表一样移动，比如 <code>[1,2,3,4,5,6,7,8,9,5]</code>用值作为索引连接起来就是<code>1 2 3 4 [5 6 7 8 9] [5 6 7 8 9] ....</code> ，时间复杂度<code>O(N)</code> 技巧性比较强，如果面试管不追问的话其实答出上面的二分就ok了</p>
<h2 id="1011-在-D-天内送达包裹的能力"><a href="#1011-在-D-天内送达包裹的能力" class="headerlink" title="1011. 在 D 天内送达包裹的能力"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/capacity-to-ship-packages-within-d-days/" >1011. 在 D 天内送达包裹的能力<i class="fas fa-external-link-alt"></i></a></h2><p>传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。</p>
<p>传送带上的第 <code>i</code> 个包裹的重量为 <code>weights[i]</code>。每一天，我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。</p>
<p>返回能在 <code>D</code> 天内将传送带上的所有包裹送达的船的最低运载能力。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：weights = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>], D = <span class="number">5</span></span><br><span class="line">输出：<span class="number">15</span></span><br><span class="line">解释：</span><br><span class="line">船舶最低载重 <span class="number">15</span> 就能够在 <span class="number">5</span> 天内送达所有包裹，如下所示：</span><br><span class="line">第 <span class="number">1</span> 天：<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span></span><br><span class="line">第 <span class="number">2</span> 天：<span class="number">6</span>, <span class="number">7</span></span><br><span class="line">第 <span class="number">3</span> 天：<span class="number">8</span></span><br><span class="line">第 <span class="number">4</span> 天：<span class="number">9</span></span><br><span class="line">第 <span class="number">5</span> 天：<span class="number">10</span></span><br><span class="line"></span><br><span class="line">请注意，货物必须按照给定的顺序装运，因此使用载重能力为 <span class="number">14</span> 的船舶并将包装分成 (<span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>), (<span class="number">1</span>, <span class="number">6</span>, <span class="number">7</span>), (<span class="number">8</span>), (<span class="number">9</span>), (<span class="number">10</span>) 是不允许的。 </span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：weights = [<span class="number">3</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">1</span>,<span class="number">4</span>], D = <span class="number">3</span></span><br><span class="line">输出：<span class="number">6</span></span><br><span class="line">解释：</span><br><span class="line">船舶最低载重 <span class="number">6</span> 就能够在 <span class="number">3</span> 天内送达所有包裹，如下所示：</span><br><span class="line">第 <span class="number">1</span> 天：<span class="number">3</span>, <span class="number">2</span></span><br><span class="line">第 <span class="number">2</span> 天：<span class="number">2</span>, <span class="number">4</span></span><br><span class="line">第 <span class="number">3</span> 天：<span class="number">1</span>, <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：weights = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>,<span class="number">1</span>], D = <span class="number">4</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：</span><br><span class="line">第 <span class="number">1</span> 天：<span class="number">1</span></span><br><span class="line">第 <span class="number">2</span> 天：<span class="number">2</span></span><br><span class="line">第 <span class="number">3</span> 天：<span class="number">3</span></span><br><span class="line">第 <span class="number">4</span> 天：<span class="number">1</span>, <span class="number">1</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ol>
<li><code>1 &lt;= D &lt;= weights.length &lt;= 50000</code></li>
<li><code>1 &lt;= weights[i] &lt;= 500</code></li>
</ol>
<p><strong>解法一</strong></p>
<p>问题的解空间是单调的，所以可以直接二分答案，然后验证是否满足条件就可以了，时间复杂度<code>O(NlogN)</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">shipWithinDays</span><span class="params">(<span class="keyword">int</span>[] weights, <span class="keyword">int</span> D)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>,max=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> w:weights)&#123;</span><br><span class="line">        max=Math.max(w,max);</span><br><span class="line">        sum+=w;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=Math.max(sum/D,max),right=sum;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(weights,mid,D))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//模拟判断</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] weights,<span class="keyword">int</span> load,<span class="keyword">int</span> D)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> temp=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> w:weights)&#123;</span><br><span class="line">        <span class="keyword">if</span>(temp+w&gt;load)&#123;</span><br><span class="line">            temp=<span class="number">0</span>;</span><br><span class="line">            D--;</span><br><span class="line">        &#125;</span><br><span class="line">        temp+=w;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//return D&gt;=0;</span></span><br><span class="line">    <span class="keyword">return</span> D&gt;<span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>上面是用的一个<a class="link"   target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1YT4y137G4" >大佬<i class="fas fa-external-link-alt"></i></a>的模板，不是之前的模板，之前的模板我刚刚写了一发，写错了。。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//之前的二分模板</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">shipWithinDays</span><span class="params">(<span class="keyword">int</span>[] weights, <span class="keyword">int</span> D)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>,max=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> w:weights)&#123;</span><br><span class="line">        max=Math.max(w,max);</span><br><span class="line">        sum+=w;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> left=Math.max(sum/D,max),right=sum;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;right)&#123; <span class="comment">//这里一开始写成&lt;=了....</span></span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(weights,mid,D))&#123;</span><br><span class="line">            right=mid;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> left;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>两种模板各有优点吧，这个大佬的模板相对更简单，但是res的初始值需要格外注意。。。</p>
<h2 id="875-爱吃香蕉的珂珂"><a href="#875-爱吃香蕉的珂珂" class="headerlink" title="875. 爱吃香蕉的珂珂"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/koko-eating-bananas/" >875. 爱吃香蕉的珂珂<i class="fas fa-external-link-alt"></i></a></h2><p>珂珂喜欢吃香蕉。这里有 <code>N</code> 堆香蕉，第 <code>i</code> 堆中有 <code>piles[i]</code> 根香蕉。警卫已经离开了，将在 <code>H</code> 小时后回来。</p>
<p>珂珂可以决定她吃香蕉的速度 <code>K</code> （单位：根/小时）。每个小时，她将会选择一堆香蕉，从中吃掉 <code>K</code> 根。如果这堆香蕉少于 <code>K</code> 根，她将吃掉这堆的所有香蕉，然后这一小时内不会再吃更多的香蕉。  </p>
<p>珂珂喜欢慢慢吃，但仍然想在警卫回来前吃掉所有的香蕉。</p>
<p>返回她可以在 <code>H</code> 小时内吃掉所有香蕉的最小速度 <code>K</code>（<code>K</code> 为整数）。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: piles = [<span class="number">3</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">11</span>], H = <span class="number">8</span></span><br><span class="line">输出: <span class="number">4</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: piles = [<span class="number">30</span>,<span class="number">11</span>,<span class="number">23</span>,<span class="number">4</span>,<span class="number">20</span>], H = <span class="number">5</span></span><br><span class="line">输出: <span class="number">30</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入: piles = [<span class="number">30</span>,<span class="number">11</span>,<span class="number">23</span>,<span class="number">4</span>,<span class="number">20</span>], H = <span class="number">6</span></span><br><span class="line">输出: <span class="number">23</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= piles.length &lt;= 10^4</code></li>
<li><code>piles.length &lt;= H &lt;= 10^9</code></li>
<li><code>1 &lt;= piles[i] &lt;= 10^9</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>一开始想用<code>sum/H</code>向上取整做左边界，结果直接爆掉了，case还是很给力啊</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//二分答案</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minEatingSpeed</span><span class="params">(<span class="keyword">int</span>[] piles, <span class="keyword">int</span> H)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> max=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> p:piles) max=Math.max(max,p);</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=max;</span><br><span class="line">    <span class="keyword">int</span> res=right;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(piles,mid,H))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] piles,<span class="keyword">int</span> k,<span class="keyword">int</span> H)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> p:piles) count+=(p-<span class="number">1</span>)/k+<span class="number">1</span>; <span class="comment">//向上取整</span></span><br><span class="line">    <span class="keyword">return</span> count&lt;=H;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1292-元素和小于等于阈值的正方形的最大边长"><a href="#1292-元素和小于等于阈值的正方形的最大边长" class="headerlink" title="1292. 元素和小于等于阈值的正方形的最大边长"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/" >1292. 元素和小于等于阈值的正方形的最大边长<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个大小为 <code>m x n</code> 的矩阵 <code>mat</code> 和一个整数阈值 <code>threshold</code>。</p>
<p>请你返回元素总和小于或等于阈值的正方形区域的最大边长；如果没有这样的正方形区域，则返回 <strong>0</strong> 。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="https://s1.ax1x.com/2020/05/17/Y2wPne.png"
                      alt="Y2wPne.png"
                ></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：mat = [[<span class="number">1</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>],[<span class="number">1</span>,<span class="number">1</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>]], threshold = <span class="number">4</span></span><br><span class="line">输出：<span class="number">2</span></span><br><span class="line">解释：总和小于 <span class="number">4</span> 的正方形的最大边长为 <span class="number">2</span>，如图所示。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：mat = [[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>],[<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">2</span>]], threshold = <span class="number">1</span></span><br><span class="line">输出：<span class="number">0</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：mat = [[<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>,<span class="number">1</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>],[<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>]], threshold = <span class="number">6</span></span><br><span class="line">输出：<span class="number">3</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：mat = [[<span class="number">18</span>,<span class="number">70</span>],[<span class="number">61</span>,<span class="number">1</span>],[<span class="number">25</span>,<span class="number">85</span>],[<span class="number">14</span>,<span class="number">40</span>],[<span class="number">11</span>,<span class="number">96</span>],[<span class="number">97</span>,<span class="number">96</span>],[<span class="number">63</span>,<span class="number">45</span>]], threshold = <span class="number">40184</span></span><br><span class="line">输出：<span class="number">2</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= m, n &lt;= 300</code></li>
<li><code>m == mat.length</code></li>
<li><code>n == mat[i].length</code></li>
<li><code>0 &lt;= mat[i][j] &lt;= 10000</code></li>
<li><code>0 &lt;= threshold &lt;= 10^5</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>这个题是个好题啊，又学到新东西了：<strong>二维前缀和</strong>，首先看到这道题就意识到了这是个二分答案的题，直接二分边长就行了，左端点<code>1</code>，右端点<code>min(m,n)</code>，某个边长<code>x</code>满足的时候，大于<code>x</code>的都满足，某个<code>x</code>不满足的时候，小于<code>x</code>的都不满足，解空间具有单调性</p>
<p>所以关键问题就是<code>check</code>怎么写，如果直接暴力枚举所有矩形然后计算时间复杂度会很恐怖，这个时候就可以引入<strong>二维前缀和</strong>，我就不具体讲解了，看看<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/solution/yuan-su-he-xiao-yu-deng-yu-yu-zhi-de-zheng-fang-2/" >官方题解<i class="fas fa-external-link-alt"></i></a>就行了，写的挺好的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxSideLength</span><span class="params">(<span class="keyword">int</span>[][] mat, <span class="keyword">int</span> threshold)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> m=mat.length;</span><br><span class="line">    <span class="keyword">int</span> n=mat[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=Math.min(m,n);</span><br><span class="line">    <span class="comment">//核心公式</span></span><br><span class="line">    <span class="comment">//sum([x1,y1]-&gt;[x2,y2])</span></span><br><span class="line">    <span class="comment">//= P[x2][y2]-P[x2][y1-1]-P[x1-1][y2]+P[x1-1][y1-1]</span></span><br><span class="line">    <span class="comment">//==&gt; mat[i][j]=P[i][j]-P[i-1][j]-P[j-1][i]+P[i-1][j-1]</span></span><br><span class="line">    <span class="keyword">int</span>[][] dp=<span class="keyword">new</span> <span class="keyword">int</span>[m+<span class="number">1</span>][n+<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i&lt;=m;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j&lt;=n;j++) &#123;</span><br><span class="line">            dp[i][j]=mat[i-<span class="number">1</span>][j-<span class="number">1</span>]+dp[i-<span class="number">1</span>][j]+dp[i][j-<span class="number">1</span>]-dp[i-<span class="number">1</span>][j-<span class="number">1</span>];</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(mat,mid,threshold,dp))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[][] mat,<span class="keyword">int</span> side,<span class="keyword">int</span> threshold,<span class="keyword">int</span>[][] dp)</span></span>&#123;</span><br><span class="line">    <span class="comment">//枚举所有的左端点</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">1</span>;i+side-<span class="number">1</span>&lt;=mat.length;i++) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j=<span class="number">1</span>;j+side-<span class="number">1</span>&lt;=mat[<span class="number">0</span>].length;j++) &#123;</span><br><span class="line">            <span class="keyword">int</span> ri=i+side-<span class="number">1</span>,rj=j+side-<span class="number">1</span>;</span><br><span class="line">            <span class="comment">//System.out.println(ri+&quot;,&quot;+rj+&quot; dp:&quot;+ dp[ri][rj]);</span></span><br><span class="line">            <span class="keyword">if</span>(dp[ri][rj]-dp[i-<span class="number">1</span>][rj]-dp[ri][j-<span class="number">1</span>]+dp[i-<span class="number">1</span>][j-<span class="number">1</span>]&lt;=threshold)&#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="1300-转变数组后最接近目标值的数组和"><a href="#1300-转变数组后最接近目标值的数组和" class="headerlink" title="1300. 转变数组后最接近目标值的数组和"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/sum-of-mutated-array-closest-to-target/" >1300. 转变数组后最接近目标值的数组和<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个整数数组 <code>arr</code> 和一个目标值 <code>target</code> ，请你返回一个整数 <code>value</code> ，使得将数组中所有大于 <code>value</code> 的值变成 <code>value</code> 后，数组的和最接近  <code>target</code> （最接近表示两者之差的绝对值最小）。</p>
<p>如果有多种使得和最接近 <code>target</code> 的方案，请你返回这些整数中的最小值。</p>
<p>请注意，答案不一定是 <code>arr</code> 中的数字。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">4</span>,<span class="number">9</span>,<span class="number">3</span>], target = <span class="number">10</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：当选择 value 为 <span class="number">3</span> 时，数组会变成 [<span class="number">3</span>, <span class="number">3</span>, <span class="number">3</span>]，和为 <span class="number">9</span> ，这是最接近 target 的方案。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">2</span>,<span class="number">3</span>,<span class="number">5</span>], target = <span class="number">10</span></span><br><span class="line">输出：<span class="number">5</span></span><br></pre></td></tr></table></figure>

<p><strong>示例 3：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：arr = [<span class="number">60864</span>,<span class="number">25176</span>,<span class="number">27249</span>,<span class="number">21296</span>,<span class="number">20204</span>], target = <span class="number">56803</span></span><br><span class="line">输出：<span class="number">11361</span></span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li><code>1 &lt;= arr.length &lt;= 10^4</code></li>
<li><code>1 &lt;= arr[i], target &lt;= 10^5</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>解空间在<code>[0,max(arr)]</code>上单调，所以可以二分答案</p>
<p>一开始傻傻的写了两个二分，一个找第一个小于等于target的，一个找大于等于的，其实根本就不用，这两个值肯定是连在一起的🤣</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">findBestValue</span><span class="params">(<span class="keyword">int</span>[] arr, <span class="keyword">int</span> target)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=Integer.MIN_VALUE;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> num:arr)&#123;</span><br><span class="line">        sum+=num;</span><br><span class="line">        right=Math.max(right,num);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span>(sum&lt;=target) <span class="keyword">return</span> right;</span><br><span class="line">    <span class="keyword">int</span> res=left;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(getSum(arr,mid)&lt;=target)&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//这两个值肯定是连在一起的</span></span><br><span class="line">    <span class="keyword">if</span>(target-getSum(arr,res)&lt;=getSum(arr,res+<span class="number">1</span>)-target)&#123;</span><br><span class="line">        <span class="keyword">return</span> res;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res+<span class="number">1</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getSum</span><span class="params">(<span class="keyword">int</span>[] arr,<span class="keyword">int</span> mid)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> a:arr)&#123;</span><br><span class="line">        sum+=a&gt;mid?mid:a;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> sum;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="LCP-12-小张刷题计划"><a href="#LCP-12-小张刷题计划" class="headerlink" title="LCP 12. 小张刷题计划"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/xiao-zhang-shua-ti-ji-hua/" >LCP 12. 小张刷题计划<i class="fas fa-external-link-alt"></i></a></h2><p>为了提高自己的代码能力，小张制定了 <code>LeetCode</code> 刷题计划，他选中了 <code>LeetCode</code> 题库中的 <code>n</code> 道题，编号从 <code>0</code> 到 <code>n-1</code>，并计划在 <code>m</code> 天内<strong>按照题目编号顺序</strong>刷完所有的题目（注意，小张不能用多天完成同一题）。</p>
<p>在小张刷题计划中，小张需要用 <code>time[i]</code> 的时间完成编号 <code>i</code> 的题目。此外，小张还可以使用场外求助功能，通过询问他的好朋友小杨题目的解法，可以省去该题的做题时间。为了防止“小张刷题计划”变成“小杨刷题计划”，小张每天最多使用一次求助。</p>
<p>我们定义 <code>m</code> 天中做题时间最多的一天耗时为 <code>T</code>（小杨完成的题目不计入做题总时间）。请你帮小张求出最小的 <code>T</code>是多少。</p>
<p><strong>示例 1：</strong></p>
<blockquote>
<p>输入：<code>time = [1,2,3,3], m = 2</code></p>
<p>输出：<code>3</code></p>
<p>解释：第一天小张完成前三题，其中第三题找小杨帮忙；第二天完成第四题，并且找小杨帮忙。这样做题时间最多的一天花费了 3 的时间，并且这个值是最小的。</p>
</blockquote>
<p><strong>示例 2：</strong></p>
<blockquote>
<p>输入：<code>time = [999,999,999], m = 4</code></p>
<p>输出：<code>0</code></p>
<p>解释：在前三天中，小张每天求助小杨一次，这样他可以在三天内完成所有的题目并不花任何时间。</p>
</blockquote>
<p><strong>限制：</strong></p>
<ul>
<li><code>1 &lt;= time.length &lt;= 10^5</code></li>
<li><code>1 &lt;= time[i] &lt;= 10000</code></li>
<li><code>1 &lt;= m &lt;= 1000</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>知道是二分答案但是check写了好久没写出来，真菜啊</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minTime</span><span class="params">(<span class="keyword">int</span>[] time, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">0</span>,right=<span class="number">0</span>;<span class="comment">//上界最多sum(time)</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;time.length;i++)&#123;</span><br><span class="line">        right+=time[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res=right+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(time,mid,m))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="comment">//其实返回left就行了,主要是避免搞混</span></span><br><span class="line">    <span class="keyword">return</span> res; </span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//核心的check</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] time,<span class="keyword">int</span> T,<span class="keyword">int</span> m)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> day=<span class="number">1</span>,sum=<span class="number">0</span>,maxt=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> t:time) &#123;</span><br><span class="line">        sum+=t;</span><br><span class="line">        maxt=Math.max(maxt,t); <span class="comment">//维护每一组的最大值</span></span><br><span class="line">        <span class="keyword">if</span>(sum-maxt&gt;T)&#123; <span class="comment">//当前组减去最大值不满足</span></span><br><span class="line">            day++;</span><br><span class="line">            sum=t;</span><br><span class="line">            maxt=t;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> day&lt;=m;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="410-分割数组的最大值"><a href="#410-分割数组的最大值" class="headerlink" title="410. 分割数组的最大值"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/split-array-largest-sum/" >410. 分割数组的最大值<i class="fas fa-external-link-alt"></i></a></h2><p>给定一个非负整数数组和一个整数 <em>m</em>，你需要将这个数组分成 <em>m</em> 个非空的连续子数组。设计一个算法使得这 <em>m</em> 个子数组各自和的最大值最小。</p>
<p><strong>注意:</strong><br>数组长度 <em>n</em> 满足以下条件:</p>
<ul>
<li>1 ≤ <em>n</em> ≤ 1000</li>
<li>1 ≤ <em>m</em> ≤ min(50, <em>n</em>)</li>
</ul>
<p><strong>示例:</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入:</span><br><span class="line">nums = [<span class="number">7</span>,<span class="number">2</span>,<span class="number">5</span>,<span class="number">10</span>,<span class="number">8</span>]</span><br><span class="line">m = <span class="number">2</span></span><br><span class="line"></span><br><span class="line">输出:</span><br><span class="line"><span class="number">18</span></span><br><span class="line"></span><br><span class="line">解释:</span><br><span class="line">一共有四种方法将nums分割为<span class="number">2</span>个子数组。</span><br><span class="line">其中最好的方式是将其分为[<span class="number">7</span>,<span class="number">2</span>,<span class="number">5</span>] 和 [<span class="number">10</span>,<span class="number">8</span>]，</span><br><span class="line">因为此时这两个子数组各自的和的最大值为<span class="number">18</span>，在所有情况中最小。</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>Hard题，但是感觉和前面的mid差不多，没啥好说的，个人感觉这题还没上面的<a href="#lcp-12-%E5%B0%8F%E5%BC%A0%E5%88%B7%E9%A2%98%E8%AE%A1%E5%88%92">LCP12.小张刷题计划</a> 难，不过有个case挺恶心，算的sum会溢出，害我WA了一次，但是他结果返回的又是个int，这就很蠢</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//一样的套路</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">splitArray</span><span class="params">(<span class="keyword">int</span>[] nums, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">long</span> left=<span class="number">0</span>,right=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> num:nums)&#123;</span><br><span class="line">        left=Math.max(left,num);</span><br><span class="line">        right+=num;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">long</span> res=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">long</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(nums,mid,m))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> (<span class="keyword">int</span>)res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//分为m组能否保证每组都小于等于mid（如果可以说明还可以更小）</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] nums,<span class="keyword">long</span> limit,<span class="keyword">int</span> m)</span></span>&#123;</span><br><span class="line">    <span class="keyword">long</span> sum=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> num:nums)&#123;</span><br><span class="line">        <span class="keyword">if</span>(sum+num&gt;limit)&#123;</span><br><span class="line">            sum=<span class="number">0</span>;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">        sum+=num;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count&lt;=m;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="NC82-分组"><a href="#NC82-分组" class="headerlink" title="NC82.分组"></a><a class="link"   target="_blank" rel="noopener" href="https://www.nowcoder.com/practice/829419bde0e946b6b4fe813ed3972db8" >NC82.分组<i class="fas fa-external-link-alt"></i></a></h2><p>题目描述<br>牛牛有一个n个数字的序列a1，a2，a3…an现在牛牛想把这个序列分成k段连续段，牛牛想知道分出来的k个连续段的段内数字和的最小值最大可以是多少？</p>
<p><strong>示例1</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入 : <span class="number">4</span>,<span class="number">2</span>,[<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">5</span>]</span><br><span class="line">输出 : <span class="number">4</span></span><br><span class="line">说明:</span><br><span class="line">有<span class="number">3</span>种分法</span><br><span class="line">[<span class="number">1</span>],[<span class="number">2</span>,<span class="number">1</span>,<span class="number">5</span>]，数字和分别为<span class="number">1</span>，<span class="number">8</span>，最小值为<span class="number">1</span></span><br><span class="line">[<span class="number">1</span>,<span class="number">2</span>][<span class="number">1</span>,<span class="number">5</span>]，数字和分别为<span class="number">3</span>，<span class="number">6</span>，最小值为<span class="number">3</span></span><br><span class="line">[<span class="number">1</span>,<span class="number">2</span>,<span class="number">1</span>],[<span class="number">5</span>]数字和分别为<span class="number">4</span>，<span class="number">5</span>，最小值为<span class="number">4</span></span><br><span class="line">则最小值的最大值为<span class="number">4</span></span><br></pre></td></tr></table></figure>
<p><strong>备注:</strong></p>
<ul>
<li>1 &lt;= k &lt;= n &lt;= 1e5</li>
<li>0 &lt;= ai &lt;= 1e4</li>
</ul>
<p>第一个参数整数n代表序列数字个数，<br>第二个参数整数k代表分出的段数，<br>第三个参数vector a 包含n个元素代表n个数字</p>
<p><strong>解法一</strong></p>
<p>我是真的菜啊，上面一题会写这题就不会写了，果然我这种菜鸡刷题就是背题，变一下就不会了。。。其实和上面的正好是反过来的，上面是要最大值最小，这里是要最小值最大，所以check的思路也是相反的，上面是验证：分为k组能否保证每组都小于等于mid。所以这题很显然就应该是：分为k组能否保证每组都大于等于mid（这里验证也是逐渐逼近答案）</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//最小值最大</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">solve</span> <span class="params">(<span class="keyword">int</span> n, <span class="keyword">int</span> k, <span class="keyword">int</span>[] a)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> right = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; a.length; i++) &#123;</span><br><span class="line">        left = Math.min(left, a[i]);</span><br><span class="line">        right += a[i];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span> (left &lt;= right) &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = left + (right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (check(mid, a, k)) &#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            left = mid + <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span> &#123;</span><br><span class="line">            right = mid - <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//分为k组能否保证每组都大于等于mid（如果可以说明还可以更大）</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span> mid, <span class="keyword">int</span>[] a, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> sum = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i &lt; a.length; i++) &#123;</span><br><span class="line">        sum += a[i];</span><br><span class="line">        <span class="keyword">if</span> (sum &gt;= mid) &#123;</span><br><span class="line">            sum = <span class="number">0</span>;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count &gt;= k;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h2 id="1482-制作-m-束花所需的最少天数"><a href="#1482-制作-m-束花所需的最少天数" class="headerlink" title="1482. 制作 m 束花所需的最少天数"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/minimum-number-of-days-to-make-m-bouquets/" >1482. 制作 m 束花所需的最少天数<i class="fas fa-external-link-alt"></i></a></h2><p>给你一个整数数组 <code>bloomDay</code>，以及两个整数 m 和 k 。</p>
<p>现需要制作 <code>m</code> 束花。制作花束时，需要使用花园中 <code>相邻的 k</code> 朵花 。</p>
<p>花园中有 n 朵花，第 i 朵花会在 bloomDay[i] 时盛开，恰好 可以用于 一束 花中。<br>请你返回从花园中摘 m 束花需要等待的最少的天数。如果不能摘到 m 束花则返回 -1 。</p>
<p><strong>示例 1：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：bloomDay = [<span class="number">1</span>,<span class="number">10</span>,<span class="number">3</span>,<span class="number">10</span>,<span class="number">2</span>], m = <span class="number">3</span>, k = <span class="number">1</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：让我们一起观察这三天的花开过程，x 表示花开，而 _ 表示花还未开。</span><br><span class="line">现在需要制作 <span class="number">3</span> 束花，每束只需要 <span class="number">1</span> 朵。</span><br><span class="line"><span class="number">1</span> 天后：[x, _, _, _, _]   <span class="comment">// 只能制作 1 束花</span></span><br><span class="line"><span class="number">2</span> 天后：[x, _, _, _, x]   <span class="comment">// 只能制作 2 束花</span></span><br><span class="line"><span class="number">3</span> 天后：[x, _, x, _, x]   <span class="comment">// 可以制作 3 束花，答案为 3</span></span><br></pre></td></tr></table></figure>
<p><strong>示例 2：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：bloomDay = [<span class="number">1</span>,<span class="number">10</span>,<span class="number">3</span>,<span class="number">10</span>,<span class="number">2</span>], m = <span class="number">3</span>, k = <span class="number">2</span></span><br><span class="line">输出：-<span class="number">1</span></span><br><span class="line">解释：要制作 <span class="number">3</span> 束花，每束需要 <span class="number">2</span> 朵花，也就是一共需要 <span class="number">6</span> 朵花。而花园中只有 <span class="number">5</span> 朵花，无法满足制作要求，返回 -<span class="number">1</span> 。</span><br></pre></td></tr></table></figure>
<p><strong>示例 3：</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">输入：bloomDay = [7,7,7,7,12,7,7], m = 2, k = 3</span><br><span class="line">输出：12</span><br><span class="line">解释：要制作 2 束花，每束需要 3 朵。</span><br><span class="line">花园在 7 天后和 12 天后的情况如下：</span><br><span class="line">7 天后：[x, x, x, x, _, x, x]</span><br><span class="line">可以用前 3 朵盛开的花制作第一束花。但不能使用后 3 朵盛开的花，因为它们不相邻。</span><br><span class="line">12 天后：[x, x, x, x, x, x, x]</span><br><span class="line">显然，我们可以用不同的方式制作两束花。</span><br></pre></td></tr></table></figure>
<p><strong>示例 4：</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line">输入：bloomDay = [<span class="number">1000000000</span>,<span class="number">1000000000</span>], m = <span class="number">1</span>, k = <span class="number">1</span></span><br><span class="line">输出：<span class="number">1000000000</span></span><br><span class="line">解释：需要等 <span class="number">1000000000</span> 天才能采到花来制作花束</span><br><span class="line">示例 <span class="number">5</span>：</span><br><span class="line"></span><br><span class="line">输入：bloomDay = [<span class="number">1</span>,<span class="number">10</span>,<span class="number">2</span>,<span class="number">9</span>,<span class="number">3</span>,<span class="number">8</span>,<span class="number">4</span>,<span class="number">7</span>,<span class="number">5</span>,<span class="number">6</span>], m = <span class="number">4</span>, k = <span class="number">2</span></span><br><span class="line">输出：<span class="number">9</span></span><br></pre></td></tr></table></figure>
<p><strong>提示：</strong></p>
<ul>
<li>bloomDay.length == n</li>
<li>1 &lt;= n &lt;= 10^5</li>
<li>1 &lt;= bloomDay[i] &lt;= 10^9</li>
<li>1 &lt;= m &lt;= 10^6</li>
<li>1 &lt;= k &lt;= n</li>
</ul>
<p><strong>解法一</strong></p>
<p>193th周赛的T3，没参加，但是在群里听群友讨论了，是个二分，刚刚具体的看了题目，发现其实是很明显的二分答案，很可惜没参加这次比赛，感觉能A3道。。。</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minDays</span><span class="params">(<span class="keyword">int</span>[] bloomDay, <span class="keyword">int</span> m, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n=bloomDay.length;</span><br><span class="line">    <span class="keyword">if</span>(m*k&gt;n) <span class="keyword">return</span> -<span class="number">1</span>; <span class="comment">//花园的花不够</span></span><br><span class="line">    <span class="comment">//直接写就完事了，这里数据范围只到1e9，log(1e9)很小的，只有30左右</span></span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=(<span class="keyword">int</span>)<span class="number">1e9</span>;</span><br><span class="line">    <span class="keyword">int</span> res=right+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(bloomDay,m,k,mid))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//check写的好丑...</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] bloomDay,<span class="keyword">int</span> m,<span class="keyword">int</span> k,<span class="keyword">int</span> day)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(i&lt;bloomDay.length)&#123;</span><br><span class="line">        <span class="keyword">int</span> temp=<span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span>(i&lt;bloomDay.length)&#123;</span><br><span class="line">            <span class="keyword">if</span>(bloomDay[i]&lt;=day)&#123;</span><br><span class="line">                temp++;</span><br><span class="line">                <span class="keyword">if</span>(temp==k)&#123;</span><br><span class="line">                    count++;</span><br><span class="line">                    <span class="keyword">break</span>;</span><br><span class="line">                &#125;</span><br><span class="line">                i++;</span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                <span class="keyword">break</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(count&gt;=m) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        i++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p><strong>解法二</strong></p>
<p>看了评论区，然后自己思考了下，改进了<code>check</code></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">minDays</span><span class="params">(<span class="keyword">int</span>[] bloomDay, <span class="keyword">int</span> m, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n=bloomDay.length;</span><br><span class="line">    <span class="keyword">if</span>(m*k&gt;n) <span class="keyword">return</span> -<span class="number">1</span>; <span class="comment">//花园的花不够</span></span><br><span class="line">    <span class="comment">//直接写就完事了，这里数据范围只到1e9，log(1e9)很小的，只有30左右</span></span><br><span class="line">    <span class="keyword">int</span> left=<span class="number">1</span>,right=(<span class="keyword">int</span>)<span class="number">1e9</span>; </span><br><span class="line">    <span class="keyword">int</span> res=right+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span>(left&lt;=right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid=left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(bloomDay,m,k,mid))&#123;</span><br><span class="line">            res=mid;</span><br><span class="line">            right=mid-<span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left=mid+<span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] bloomDay,<span class="keyword">int</span> m,<span class="keyword">int</span> k,<span class="keyword">int</span> day)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count=<span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> temp=<span class="number">0</span>; <span class="comment">//相邻的开花数量</span></span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> d:bloomDay)&#123;</span><br><span class="line">        <span class="keyword">if</span>(d&lt;=day)&#123; <span class="comment">//花开了(md，这个if写反两次)</span></span><br><span class="line">            temp++;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            temp=<span class="number">0</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">if</span>(temp==k)&#123;</span><br><span class="line">            temp=<span class="number">0</span>;</span><br><span class="line">            count++;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count&gt;=m;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="378-有序矩阵中第K小的元素"><a href="#378-有序矩阵中第K小的元素" class="headerlink" title="378. 有序矩阵中第K小的元素"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/" >378. 有序矩阵中第K小的元素<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>给定一个 _<code>n x n</code> _矩阵，其中每行和每列元素均按升序排序，找到矩阵中第 <code>k</code> 小的元素。<br>请注意，它是排序后的第 <code>k</code> 小元素，而不是第 <code>k</code> 个不同的元素。</p>
<p><strong>示例：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">matrix = [</span><br><span class="line">   [ <span class="number">1</span>,  <span class="number">5</span>,  <span class="number">9</span>],</span><br><span class="line">   [<span class="number">10</span>, <span class="number">11</span>, <span class="number">13</span>],</span><br><span class="line">   [<span class="number">12</span>, <span class="number">13</span>, <span class="number">15</span>]</span><br><span class="line">],</span><br><span class="line">k = <span class="number">8</span>,</span><br><span class="line"></span><br><span class="line">返回 <span class="number">13</span>。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong><br>你可以假设 k 的值永远是有效的，<code>1 ≤ k ≤ n&lt;sup&gt;2 &lt;/sup&gt;</code>。</p>
<p>（直接搬运我在lc题解区写的<a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/kth-smallest-element-in-a-sorted-matrix/solution/java-xiao-gen-dui-er-fen-da-an-chang-shi-jie-shi-e/" >题解<i class="fas fa-external-link-alt"></i></a>）</p>
<p><strong>解法一</strong></p>
<p>小根堆，多路归并，没啥好说的</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">kthSmallest</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    PriorityQueue&lt;Pair&gt; pq = <span class="keyword">new</span> PriorityQueue&lt;&gt;((p1,p2)-&gt;matrix[p1.x][p1.y] - matrix[p2.x][p2.y]);</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i &lt; matrix.length; i++)&#123;</span><br><span class="line">        pq.add(<span class="keyword">new</span> Pair(i, <span class="number">0</span>));  </span><br><span class="line">    &#125; </span><br><span class="line">    <span class="keyword">while</span>(k &gt; <span class="number">1</span>)&#123;</span><br><span class="line">        Pair pair = pq.poll();</span><br><span class="line">        <span class="keyword">if</span>(pair.y + <span class="number">1</span> &lt; matrix[<span class="number">0</span>].length)&#123;</span><br><span class="line">            pq.add(<span class="keyword">new</span> Pair(pair.x, pair.y+<span class="number">1</span>));   </span><br><span class="line">        &#125;</span><br><span class="line">        k--;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> matrix[pq.peek().x][pq.peek().y];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Pair</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> x, y;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Pair</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y)</span></span>&#123;</span><br><span class="line">        <span class="keyword">this</span>.x = x;</span><br><span class="line">        <span class="keyword">this</span>.y = y;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>解法二</strong></p>
<p>二分答案，我们求的元素一定是在<code>matrix[0][0]~matrix[n-1][n-1]</code>之间，取中间某个元素<code>mid</code>，大于<code>mid</code>的都分布在右下角，小于<code>mid</code>的的分布在右上角，越往右上走，小于<code>mid</code>的元素就越少，大于<code>mid</code>的元素就越多，所以整体是具有单调性的，所以可以二分</p>
<p>然后我认为很关键的一个地方就是二分的写法，我这里用的是 <a class="link"   target="_blank" rel="noopener" href="https://www.bilibili.com/video/BV1YT4y137G4" >zls的一个二分模板<i class="fas fa-external-link-alt"></i></a>，两个分支，一个是答案区间，一个是排除区间，在答案区间记录答案，现在问题就是：是用 <code>&lt;=</code> 作为答案区间，还是用 <code>&gt;=</code>做为答案区间？</p>
<p>两种方法的区别就是区间收缩的方式不一样，前者是<code>left=mid+1</code>后者是<code>right=mid-1</code>，所以问题其实就变成了：当<strong>小于等于mid的数量==k</strong>的时候，二分的区间应该如何缩减？</p>
<p>其实举个例子就懂了</p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">matrix = [</span><br><span class="line">   [ <span class="number">1</span>,  <span class="number">5</span>,  <span class="number">9</span>],</span><br><span class="line">   [<span class="number">10</span>, <span class="number">11</span>, <span class="number">13</span>],</span><br><span class="line">   [<span class="number">12</span>, <span class="number">13</span>, <span class="number">15</span>]</span><br><span class="line">],</span><br><span class="line">k = <span class="number">2</span></span><br></pre></td></tr></table></figure>
<p>k=2，对应结果应该是5，但是我们现在mid=8，这里8和5在矩阵中小于等于它们的数量是相同的，这个时候很明显应该缩短right去逼近5，所以我们应该选取<code>&gt;=</code>作为答案区间并记录答案，并且缩短right逼近矩阵中真实存在的值</p>
<blockquote>
<p>这里是一定是可以取到矩阵中的值的，二分最后会在大于等于区域不断缩减right直至不能再缩减，也就是缩减成为矩阵中的元素（再缩减就小于K了）</p>
</blockquote>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">kthSmallest</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> n = matrix.length;</span><br><span class="line">    <span class="keyword">int</span> left = matrix[<span class="number">0</span>][<span class="number">0</span>];</span><br><span class="line">    <span class="keyword">int</span> right = matrix[n-<span class="number">1</span>][n-<span class="number">1</span>];</span><br><span class="line">    <span class="keyword">int</span> res = left;</span><br><span class="line">    <span class="keyword">while</span>(left &lt;= right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid = left + (right - left)/<span class="number">2</span>;</span><br><span class="line">        <span class="comment">//注意这个地方，很关键，核心就是这个等于号的位置，在小于等于mid的数量==k的时候二分的区间应该如何移动</span></span><br><span class="line">        <span class="comment">//其实举个例子就懂了，假设k=2，对于结果应该是5，但是我们现在mid=8</span></span><br><span class="line">        <span class="comment">//这里8和5在矩阵中小于等于它们的数量是相同的，这个时候很明显应该缩短right去逼近5</span></span><br><span class="line">        <span class="comment">//所以我们应该在二分的大于等于区间记录答案，并且缩短right</span></span><br><span class="line">        <span class="keyword">if</span> (check(matrix, mid) &gt;= k)&#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            right = mid - <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left = mid + <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">//检查数组中小于等于mid的个数</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[][] matrix, <span class="keyword">int</span> mid)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> row = matrix.length-<span class="number">1</span>, column = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> lastRow = <span class="number">0</span>; </span><br><span class="line">    <span class="keyword">while</span>(row &gt;= <span class="number">0</span>)&#123;</span><br><span class="line">        <span class="keyword">while</span> (column &lt; matrix[<span class="number">0</span>].length &amp;&amp; matrix[row][column] &lt;= mid)&#123;</span><br><span class="line">            column++;</span><br><span class="line">            lastRow++;</span><br><span class="line">        &#125;</span><br><span class="line">        count += lastRow;</span><br><span class="line">        row--;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="441-排列硬币"><a href="#441-排列硬币" class="headerlink" title="441. 排列硬币"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/arranging-coins/" >441. 排列硬币<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>简单</strong></p>
<p>你总共有 _n _枚硬币，你需要将它们摆成一个阶梯形状，第 _k _行就必须正好有 _k _枚硬币。</p>
<p>给定一个数字 _n_，找出可形成完整阶梯行的总行数。</p>
<p>_n _是一个非负整数，并且在32位有符号整型的范围内。</p>
<p><strong>示例 1:</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">n = 5</span><br><span class="line"></span><br><span class="line">硬币可排列成以下几行:</span><br><span class="line">¤</span><br><span class="line">¤ ¤</span><br><span class="line">¤ ¤</span><br><span class="line"></span><br><span class="line">因为第三行不完整，所以返回2.</span><br></pre></td></tr></table></figure>

<p><strong>示例 2:</strong></p>
<figure class="highlight plaintext"><table><tr><td class="code"><pre><span class="line">n = 8</span><br><span class="line"></span><br><span class="line">硬币可排列成以下几行:</span><br><span class="line">¤</span><br><span class="line">¤ ¤</span><br><span class="line">¤ ¤ ¤</span><br><span class="line">¤ ¤</span><br><span class="line"></span><br><span class="line">因为第四行不完整，所以返回3.</span><br></pre></td></tr></table></figure>
<p><strong>解法一</strong></p>
<p>因为是从二分的tag来的，所以知道是二分，然后看了题，确定了有二分答案性质，然后直接二分，可是没想到居然溢出了，看来还是有点大意了啊，时间复杂度O(logN)</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//二分答案</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">arrangeCoins</span><span class="params">(<span class="keyword">int</span> n)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> right = n;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left &lt;= right)&#123;</span><br><span class="line">        <span class="keyword">long</span> mid = left + (right - left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">long</span> sum = (<span class="number">1</span> + mid) * mid / <span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(sum &lt;= n)&#123;</span><br><span class="line">            res = (<span class="keyword">int</span>)mid;</span><br><span class="line">            left = (<span class="keyword">int</span>)mid + <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = (<span class="keyword">int</span>)mid - <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题当然也可以直接模拟，不过意义不大，这题还有数学的解法，根据求和公式直接算出根，然后利用sqrt函数，这样并不会比二分快多少，sqrt也是logN级别的，而且面试官应该也不希望你利用库函数（当然人如果能手写牛顿迭代法那肯定没问题）</p>
<h2 id="174-地下城游戏"><a href="#174-地下城游戏" class="headerlink" title="174. 地下城游戏"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/dungeon-game/" >174. 地下城游戏<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>困难</strong></p>
<p>一些恶魔抓住了公主（<strong>P</strong>）并将她关在了地下城的右下角。地下城是由 M x N 个房间组成的二维网格。我们英勇的骑士（<strong>K</strong>）最初被安置在左上角的房间里，他必须穿过地下城并通过对抗恶魔来拯救公主。</p>
<p>骑士的初始健康点数为一个正整数。如果他的健康点数在某一时刻降至 0 或以下，他会立即死亡。</p>
<p>有些房间由恶魔守卫，因此骑士在进入这些房间时会失去健康点数（若房间里的值为负整数，则表示骑士将损失健康点数）；其他房间要么是空的（房间里的值为 0），要么包含增加骑士健康点数的魔法球（若房间里的值为正整数，则表示骑士将增加健康点数）。</p>
<p>为了尽快到达公主，骑士决定每次只向右或向下移动一步。</p>
<p><strong>编写一个函数来计算确保骑士能够拯救到公主所需的最低初始健康点数。</strong></p>
<p>例如，考虑到如下布局的地下城，如果骑士遵循最佳路径 <code>右 -&gt; 右 -&gt; 下 -&gt; 下</code>，则骑士的初始健康点数至少为 <strong>7</strong>。</p>
<table class="dungeon" style="display: table;">

<tbody style="display: table-row-group;">

<tr style="display: table-row;">

<td style="display: table-cell;">-2 (K)</td>

<td style="display: table-cell;">-3</td>

<td style="display: table-cell;">3</td>

</tr>

<tr style="display: table-row;">

<td style="display: table-cell;">-5</td>

<td style="display: table-cell;">-10</td>

<td style="display: table-cell;">1</td>

</tr>

<tr style="display: table-row;">

<td style="display: table-cell;">10</td>

<td style="display: table-cell;">30</td>

<td style="display: table-cell;">-5 (P)</td>

</tr>

</tbody>

</table>

<p><strong>说明:</strong></p>
<ul>
<li><p>  骑士的健康点数没有上限。</p>
</li>
<li><p>  任何房间都可能对骑士的健康点数造成威胁，也可能增加骑士的健康点数，包括骑士进入的左上角房间以及公主被监禁的右下角房间。</p>
</li>
</ul>
<p><strong>解法一</strong></p>
<p>以后每日一题没写出来之前绝壁不看群了，看了一眼群，看见群友讨论了这题，说了二分和dp，然后我就直接向二分的方向去想了，如果独立的想的话，应该也是可以得出二分的解法的，毕竟题目的描述很明显就是二分答案，<strong>最低的健康血量</strong>，大于这个血量的肯定可以救出来，小于这个血量的肯定救不出来，所以check就是判断在某个血量下，能否拯救到公主（DP）</p>
<p>时间复杂度O(N^2logN)（其实我认为也可以当作N^2毕竟上下界都确定了，logN也就30左右），这种解法也挺不错的，融合了二分和dp</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">calculateMinimumHP</span><span class="params">(<span class="keyword">int</span>[][] dungeon)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> right = Integer.MAX_VALUE;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">while</span>(left &lt;= right)&#123;</span><br><span class="line">        <span class="keyword">int</span> mid = left + (right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span>(check(dungeon, mid))&#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            right = mid - <span class="number">1</span>;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left = mid + <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[][] dungeon, <span class="keyword">int</span> live)</span></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> m = dungeon.length;</span><br><span class="line">    <span class="keyword">int</span> n = dungeon[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span> INF = Integer.MIN_VALUE;</span><br><span class="line">    <span class="comment">//live的血量从左上到dungeon[i][j]的剩余最多血量</span></span><br><span class="line">    <span class="keyword">int</span>[][] dp = <span class="keyword">new</span> <span class="keyword">int</span>[m+<span class="number">1</span>][n+<span class="number">1</span>];</span><br><span class="line">    <span class="comment">//地牢外围加上INF的围墙，简化逻辑</span></span><br><span class="line">    Arrays.fill(dp[<span class="number">0</span>], INF);</span><br><span class="line">    dp[<span class="number">0</span>][<span class="number">1</span>] = live;</span><br><span class="line">    <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i &lt;= m; i++)&#123;</span><br><span class="line">        dp[i][<span class="number">0</span>] = INF;</span><br><span class="line">        <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j &lt;= n; j++)&#123;</span><br><span class="line">            <span class="keyword">if</span>(dp[i-<span class="number">1</span>][j] &lt;= <span class="number">0</span> &amp;&amp; dp[i][j-<span class="number">1</span>] &lt;=<span class="number">0</span> )&#123;</span><br><span class="line">                dp[i][j] = INF; <span class="comment">//无法到达这里</span></span><br><span class="line">            &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">                dp[i][j] = dungeon[i-<span class="number">1</span>][j-<span class="number">1</span>] + Math.max(dp[i][j-<span class="number">1</span>], dp[i-<span class="number">1</span>][j]);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[m][n] &gt; <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>当然这题也有纯dp的做法，很可惜，我压根没往上面想，我只想着二分dp，写完了AC之后就去看评论区了，结果发现大家都是直接dp的。。。然后还看到了一个关键词：逆向dp，然后赶紧关了评论区回来写了下面的dp解法</p>
<p><strong>解法二</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">    -2  -3  3</span></span><br><span class="line"><span class="comment">    -5 -10  1</span></span><br><span class="line"><span class="comment">    10  30 -5 1</span></span><br><span class="line"><span class="comment">            </span></span><br><span class="line"><span class="comment">    7   5   2</span></span><br><span class="line"><span class="comment">    6  11   5</span></span><br><span class="line"><span class="comment">    1   1   6</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">calculateMinimumHP</span><span class="params">(<span class="keyword">int</span>[][] dungeon)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> m = dungeon.length;</span><br><span class="line">    <span class="keyword">int</span> n = dungeon[<span class="number">0</span>].length;</span><br><span class="line">    <span class="keyword">int</span> INF = Integer.MAX_VALUE;</span><br><span class="line">    <span class="comment">//从dungeon[i-1][j-1]到右下角至少要多少血量</span></span><br><span class="line">    <span class="keyword">int</span>[][] dp = <span class="keyword">new</span> <span class="keyword">int</span>[m+<span class="number">1</span>][n+<span class="number">1</span>];</span><br><span class="line">    Arrays.fill(dp[m], INF);<span class="comment">//末行</span></span><br><span class="line">    dp[m][n-<span class="number">1</span>] = <span class="number">1</span>; <span class="comment">//初始血量</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = m-<span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        dp[i][n] = INF; <span class="comment">//首列和尾列</span></span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">int</span> j = n-<span class="number">1</span>; j &gt;= <span class="number">0</span>; j--) &#123;</span><br><span class="line">            dp[i][j] = Math.max(Math.min(dp[i+<span class="number">1</span>][j], dp[i][j+<span class="number">1</span>]) - dungeon[i][j], <span class="number">1</span>);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> dp[<span class="number">0</span>][<span class="number">0</span>];</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这题为啥不能正向dp呢，设<code>dp[i][j]</code>为从左上角到i,j所需要的最低血量? 其实这个很明显就是有问题的，没办法转移，<code>dp[i][j]</code>和<code>dp[i-1][j]</code>没有任何关系，都不一定是同一条路径</p>
<h2 id="848-加油站之间的最小距离（LintCode）"><a href="#848-加油站之间的最小距离（LintCode）" class="headerlink" title="848. 加油站之间的最小距离（LintCode）"></a><a class="link"   target="_blank" rel="noopener" href="https://www.lintcode.com/problem/minimize-max-distance-to-gas-station/description" >848. 加油站之间的最小距离（LintCode）<i class="fas fa-external-link-alt"></i></a></h2><p>在水平数轴上，我们有加油站：stations[0], stations[1], …, stations[N-1], 这里N = stations.length。</p>
<p>现在，我们再增加K个加油站，D表示相邻加油站之间的最大距离，这样D就变小了。</p>
<p>返回所有可能值D中最小值。</p>
<ol>
<li>stations.length 为整数，范围 [10, 2000].</li>
<li>stations[i] 为整数，范围 [0, 10^8].</li>
<li>K 为整数，范围 [1, 10^6].</li>
<li>答案范围在10 ^ -6之内的有理数。</li>
</ol>
<p><strong>样例 1:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：stations = [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>, <span class="number">10</span>]，K = <span class="number">9</span></span><br><span class="line">输出：<span class="number">0.50</span></span><br><span class="line">解释：相邻加油站的距离均为<span class="number">0.50</span></span><br></pre></td></tr></table></figure>
<p><strong>样例 2:</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：stations = [<span class="number">3</span>,<span class="number">6</span>,<span class="number">12</span>,<span class="number">19</span>,<span class="number">33</span>,<span class="number">44</span>,<span class="number">67</span>,<span class="number">72</span>,<span class="number">89</span>,<span class="number">95</span>]，K = <span class="number">2</span></span><br><span class="line">输出：<span class="number">14.00</span></span><br><span class="line">解释：在距离<span class="number">86</span>处建造加油站(fix: 还有<span class="number">58</span>处)</span><br></pre></td></tr></table></figure>

<p><strong>解法一</strong></p>
<p>二分答案的性质很明显，但是这里和之前的不一样，这里是浮点数二分，和整数的不太一样，浮点数/2的时候都是实际的一分为2，不会有整除的问题，同时题目给出了eps=1e-6，只要left和right误差在这个范围内就是合法的，并不是要求left和right相等，这里还有一个问题，就是这里如果eps太小的话由于精度问题还是可能会tle，这个时候就可以采取固定循环次数的方式逼近，一般取100，200就够了</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">double</span> <span class="title">minmaxGasDist</span><span class="params">(<span class="keyword">int</span>[] stations, <span class="keyword">int</span> k)</span> </span>&#123;</span><br><span class="line">    <span class="comment">// Write your code here</span></span><br><span class="line">    <span class="keyword">double</span> left = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">double</span> right = <span class="number">1e8</span>+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">double</span> res = right;</span><br><span class="line">    <span class="comment">//for (int i = 0; i &lt;= 100; i++)&#123;</span></span><br><span class="line">    <span class="keyword">while</span> (right-left &gt;= <span class="number">1e-6</span>)&#123;</span><br><span class="line">        <span class="keyword">double</span> mid = left+(right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (check(stations, k, mid)) &#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            right = mid;</span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            left = mid;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] stations, <span class="keyword">int</span> k, <span class="keyword">double</span> D)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> count = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; stations.length; i++) &#123;</span><br><span class="line">        count += (stations[i]-stations[i-<span class="number">1</span>]) / D;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> count &lt;= k;        </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="5489-两球之间的磁力"><a href="#5489-两球之间的磁力" class="headerlink" title="5489. 两球之间的磁力"></a><a class="link"   target="_blank" rel="noopener" href="https://leetcode-cn.com/problems/magnetic-force-between-two-balls/" >5489. 两球之间的磁力<i class="fas fa-external-link-alt"></i></a></h2><p>Difficulty: <strong>中等</strong></p>
<p>在代号为 C-137 的地球上，Rick 发现如果他将两个球放在他新发明的篮子里，它们之间会形成特殊形式的磁力。Rick 有 <code>n</code> 个空的篮子，第 <code>i</code> 个篮子的位置在 <code>position[i]</code> ，Morty 想把 <code>m</code> 个球放到这些篮子里，使得任意两球间 <strong>最小磁力</strong> 最大。</p>
<p>已知两个球如果分别位于 <code>x</code> 和 <code>y</code> ，那么它们之间的磁力为 <code>|x - y|</code> 。</p>
<p>给你一个整数数组 <code>position</code> 和一个整数 <code>m</code> ，请你返回最大化的最小磁力。</p>
<p><strong>示例 1：</strong></p>
<p><img  
                     lazyload
                     src="/images/loading.svg"
                     data-src="http://static.imlgw.top/blog/20200816/1KmEXzfFOozs.png?imageslim"
                      alt="mark"
                ></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：position = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">7</span>], m = <span class="number">3</span></span><br><span class="line">输出：<span class="number">3</span></span><br><span class="line">解释：将 <span class="number">3</span> 个球分别放入位于 <span class="number">1</span>，<span class="number">4</span> 和 <span class="number">7</span> 的三个篮子，两球间的磁力分别为 [<span class="number">3</span>, <span class="number">3</span>, <span class="number">6</span>]。最小磁力为 <span class="number">3</span> 。我们没办法让最小磁力大于 <span class="number">3</span> 。</span><br></pre></td></tr></table></figure>

<p><strong>示例 2：</strong></p>
<figure class="highlight go"><table><tr><td class="code"><pre><span class="line">输入：position = [<span class="number">5</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>,<span class="number">1000000000</span>], m = <span class="number">2</span></span><br><span class="line">输出：<span class="number">999999999</span></span><br><span class="line">解释：我们使用位于 <span class="number">1</span> 和 <span class="number">1000000000</span> 的篮子时最小磁力最大。</span><br></pre></td></tr></table></figure>

<p><strong>提示：</strong></p>
<ul>
<li>  <code>n == position.length</code></li>
<li>  <code>2 &lt;= n &lt;= 10^5</code></li>
<li>  <code>1 &lt;= position[i] &lt;= 10^9</code></li>
<li>  所有 <code>position</code> 中的整数 <strong>互不相同</strong> 。</li>
<li>  <code>2 &lt;= m &lt;= position.length</code></li>
</ul>
<p><strong>解法一</strong></p>
<p>202周赛T3，没参赛（实在是没时间打）赛后独立的写出来了，很明显是二分答案，不过这里有一点小不同</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">maxDistance</span><span class="params">(<span class="keyword">int</span>[] position, <span class="keyword">int</span> m)</span> </span>&#123;</span><br><span class="line">    Arrays.sort(position);</span><br><span class="line">    <span class="keyword">int</span> left = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> right = (<span class="keyword">int</span>)<span class="number">1e9</span>+<span class="number">1</span>;</span><br><span class="line">    <span class="keyword">int</span> res = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">while</span> (left &lt;= right) &#123;</span><br><span class="line">        <span class="keyword">int</span> mid = left + (right-left)/<span class="number">2</span>;</span><br><span class="line">        <span class="keyword">if</span> (check(position, m, mid)) &#123;</span><br><span class="line">            res = mid;</span><br><span class="line">            left = mid + <span class="number">1</span>; </span><br><span class="line">        &#125;<span class="keyword">else</span>&#123;</span><br><span class="line">            right = mid - <span class="number">1</span>;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> res;</span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//1  1000 2000 3000 m=3</span></span><br><span class="line"><span class="comment">//验证在距离至少为force的情况下能否放下所有的球，然后增大force逼近答案</span></span><br><span class="line"><span class="comment">//所以check验证成功的不一定是合法的答案，但是最终一定会到达real ans</span></span><br><span class="line"><span class="comment">//类似【378. 有序矩阵中第K小的元素】这道题</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span>[] position, <span class="keyword">int</span> m, <span class="keyword">int</span> force)</span> </span>&#123;</span><br><span class="line">    <span class="keyword">int</span> last = position[<span class="number">0</span>];</span><br><span class="line">    m--;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>; i &lt; position.length; i++) &#123;</span><br><span class="line">        <span class="keyword">if</span> (position[i]-last &lt; force) &#123;</span><br><span class="line">            <span class="keyword">continue</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        last = position[i];</span><br><span class="line">        m--;</span><br><span class="line">        <span class="keyword">if</span> (m==<span class="number">0</span>) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>check类似<a href="#378-%E6%9C%89%E5%BA%8F%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%AC%ACk%E5%B0%8F%E7%9A%84%E5%85%83%E7%B4%A0">378. 有序矩阵中第K小的元素</a>这道题，都是逼近答案，而不是验证答案，其实一开始我的check不是这样写的，写的很丑，这里看了别人的写法发现continue有时候还是挺好用的</p>

        </div>

        
            <div class="post-copyright-info">
                <div class="article-copyright-info-container">
    <ul>
        <li>本文标题：LeetCode二分查找</li>
        <li>本文作者：Resolmi</li>
        <li>创建时间：2019-12-06 00:00:00</li>
        <li>
            本文链接：https://imlgw.top/2019/12/06/ac033e1a/
        </li>
        <li>
            版权声明：本博客所有文章除特别声明外，均采用 <a class="license" target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">BY-NC-SA</a> 许可协议。转载请注明出处！
        </li>
    </ul>
</div>

            </div>
        

        
            <div class="article-nav">
                
                    <div class="article-prev">
                        <a class="prev"
                           rel="prev"
                           href="/2019/12/08/6ff78e85/"
                        >
                            <span class="left arrow-icon flex-center">
                              <i class="fas fa-chevron-left"></i>
                            </span>
                            <span class="title flex-center">
                                <span class="post-nav-title-item">由于cmd引发的血案</span>
                                <span class="post-nav-item">上一篇</span>
                            </span>
                        </a>
                    </div>
                
                
                    <div class="article-next">
                        <a class="next"
                           rel="next"
                           href="/2019/12/01/4bb85ba2/"
                        >
                            <span class="title flex-center">
                                <span class="post-nav-title-item">堆和优先队列</span>
                                <span class="post-nav-item">下一篇</span>
                            </span>
                            <span class="right arrow-icon flex-center">
                              <i class="fas fa-chevron-right"></i>
                            </span>
                        </a>
                    </div>
                
            </div>
        

        
            <div class="comment-container">
                <div class="comments-container">
    <div id="comment-anchor"></div>
    <div class="comment-area-title">
        <i class="fas fa-comments">&nbsp;评论</i>
    </div>
    

        
            <section class="disqus-comments">
<div id="disqus_thread">
  <noscript>Please enable JavaScript to view the <a target="_blank" rel="noopener" href="//disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
</div>
</section>

<script>
var disqus_shortname = 'imlgw';

var disqus_url = 'https://imlgw.top/2019/12/06/ac033e1a/';

(function(){
  var dsq = document.createElement('script');
  dsq.type = 'text/javascript';
  dsq.async = true;
  dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>

<script id="dsq-count-scr" src="//imlgw.disqus.com/count.js" async></script>
        
    
</div>

            </div>
        
    </div>
</div>


                
            </div>

        </div>

        <div class="page-main-content-bottom">
            <footer class="footer">
    <div class="info-container">
        <div class="copyright-info info-item">
            &copy;
            
              <span>2018</span>&nbsp;-&nbsp;
            
            2021&nbsp;<i class="fas fa-heart icon-animate"></i>&nbsp;<a href="/">Resolmi</a>
        </div>
        
            <script async data-pjax src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
            <div class="website-count info-item">
                
                    <span id="busuanzi_container_site_uv">
                        访问人数&nbsp;<span id="busuanzi_value_site_uv"></span>&ensp;
                    </span>
                
                
                    <span id="busuanzi_container_site_pv">
                        总访问量&nbsp;<span id="busuanzi_value_site_pv"></span>
                    </span>
                
            </div>
        
        
            <div class="icp-info info-item"><a target="_blank" rel="nofollow" href="https://beian.miit.gov.cn">鄂ICP备18011208号</a></div>
        
    </div>
</footer>

        </div>
    </div>

    
        <div class="post-tools">
            <div class="post-tools-container">
    <ul class="tools-list">
        <!-- TOC aside toggle -->
        
            <li class="tools-item page-aside-toggle">
                <i class="fas fa-outdent"></i>
            </li>
        

        <!-- go comment -->
        
            <li class="go-comment">
                <i class="fas fa-comment"></i>
            </li>
        
    </ul>
</div>

        </div>
    

    <div class="right-bottom-side-tools">
        <div class="side-tools-container">
    <ul class="side-tools-list">
        <li class="tools-item tool-font-adjust-plus flex-center">
            <i class="fas fa-search-plus"></i>
        </li>

        <li class="tools-item tool-font-adjust-minus flex-center">
            <i class="fas fa-search-minus"></i>
        </li>

        <li class="tools-item tool-expand-width flex-center">
            <i class="fas fa-arrows-alt-h"></i>
        </li>

        <li class="tools-item tool-dark-light-toggle flex-center">
            <i class="fas fa-moon"></i>
        </li>

        <!-- rss -->
        

        

        <li class="tools-item tool-scroll-to-bottom flex-center">
            <i class="fas fa-arrow-down"></i>
        </li>
    </ul>

    <ul class="exposed-tools-list">
        <li class="tools-item tool-toggle-show flex-center">
            <i class="fas fa-cog fa-spin"></i>
        </li>
        
            <li class="tools-item tool-scroll-to-top flex-center">
                <i class="arrow-up fas fa-arrow-up"></i>
                <span class="percent"></span>
            </li>
        
    </ul>
</div>

    </div>

    
        <aside class="page-aside">
            <div class="post-toc-wrap">
    <div class="post-toc">
        <ol class="nav"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2"><span class="nav-number">1.</span> <span class="nav-text">二分搜索</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#704-%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE"><span class="nav-number">2.</span> <span class="nav-text">704. 二分查找</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#69-x-%E7%9A%84%E5%B9%B3%E6%96%B9%E6%A0%B9"><span class="nav-number">3.</span> <span class="nav-text">69. x 的平方根</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#35-%E6%90%9C%E7%B4%A2%E6%8F%92%E5%85%A5%E4%BD%8D%E7%BD%AE"><span class="nav-number">4.</span> <span class="nav-text">35. 搜索插入位置</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#153-%E5%AF%BB%E6%89%BE%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9C%80%E5%B0%8F%E5%80%BC"><span class="nav-number">5.</span> <span class="nav-text">153. 寻找旋转排序数组中的最小值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#154-%E5%AF%BB%E6%89%BE%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E7%9A%84%E6%9C%80%E5%B0%8F%E5%80%BC-II"><span class="nav-number">6.</span> <span class="nav-text">154. 寻找旋转排序数组中的最小值 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#33-%E6%90%9C%E7%B4%A2%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84"><span class="nav-number">7.</span> <span class="nav-text">33. 搜索旋转排序数组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#81-%E6%90%9C%E7%B4%A2%E6%97%8B%E8%BD%AC%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84-II"><span class="nav-number">8.</span> <span class="nav-text">81. 搜索旋转排序数组 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#744-%E5%AF%BB%E6%89%BE%E6%AF%94%E7%9B%AE%E6%A0%87%E5%AD%97%E6%AF%8D%E5%A4%A7%E7%9A%84%E6%9C%80%E5%B0%8F%E5%AD%97%E6%AF%8D"><span class="nav-number">9.</span> <span class="nav-text">744. 寻找比目标字母大的最小字母</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#34-%E5%9C%A8%E6%8E%92%E5%BA%8F%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E5%85%83%E7%B4%A0%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%92%8C%E6%9C%80%E5%90%8E%E4%B8%80%E4%B8%AA%E4%BD%8D%E7%BD%AE"><span class="nav-number">10.</span> <span class="nav-text">34. 在排序数组中查找元素的第一个和最后一个位置</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E9%9D%A2%E8%AF%95%E9%A2%9853-II-0%EF%BD%9En-1%E4%B8%AD%E7%BC%BA%E5%A4%B1%E7%9A%84%E6%95%B0%E5%AD%97"><span class="nav-number">11.</span> <span class="nav-text">面试题53 - II. 0～n-1中缺失的数字</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#852-%E5%B1%B1%E8%84%89%E6%95%B0%E7%BB%84%E7%9A%84%E5%B3%B0%E9%A1%B6%E7%B4%A2%E5%BC%95"><span class="nav-number">12.</span> <span class="nav-text">852. 山脉数组的峰顶索引</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1095-%E5%B1%B1%E8%84%89%E6%95%B0%E7%BB%84%E4%B8%AD%E6%9F%A5%E6%89%BE%E7%9B%AE%E6%A0%87%E5%80%BC"><span class="nav-number">13.</span> <span class="nav-text">1095. 山脉数组中查找目标值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#162-%E5%AF%BB%E6%89%BE%E5%B3%B0%E5%80%BC"><span class="nav-number">14.</span> <span class="nav-text">162. 寻找峰值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#74-%E6%90%9C%E7%B4%A2%E4%BA%8C%E7%BB%B4%E7%9F%A9%E9%98%B5"><span class="nav-number">15.</span> <span class="nav-text">74. 搜索二维矩阵</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#240-%E6%90%9C%E7%B4%A2%E4%BA%8C%E7%BB%B4%E7%9F%A9%E9%98%B5-II"><span class="nav-number">16.</span> <span class="nav-text">240. 搜索二维矩阵 II</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1351-%E7%BB%9F%E8%AE%A1%E6%9C%89%E5%BA%8F%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%9A%84%E8%B4%9F%E6%95%B0"><span class="nav-number">17.</span> <span class="nav-text">1351. 统计有序矩阵中的负数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-%E5%AF%BB%E6%89%BE%E4%B8%A4%E4%B8%AA%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E4%B8%AD%E4%BD%8D%E6%95%B0"><span class="nav-number">18.</span> <span class="nav-text">4. 寻找两个有序数组的中位数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#658-%E6%89%BE%E5%88%B0-K-%E4%B8%AA%E6%9C%80%E6%8E%A5%E8%BF%91%E7%9A%84%E5%85%83%E7%B4%A0"><span class="nav-number">19.</span> <span class="nav-text">658. 找到 K 个最接近的元素</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#367-%E6%9C%89%E6%95%88%E7%9A%84%E5%AE%8C%E5%85%A8%E5%B9%B3%E6%96%B9%E6%95%B0"><span class="nav-number">20.</span> <span class="nav-text">367. 有效的完全平方数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#475-%E4%BE%9B%E6%9A%96%E5%99%A8"><span class="nav-number">21.</span> <span class="nav-text">475. 供暖器</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8C%E5%88%86%E7%AD%94%E6%A1%88"><span class="nav-number">22.</span> <span class="nav-text">二分答案</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1283-%E4%BD%BF%E7%BB%93%E6%9E%9C%E4%B8%8D%E8%B6%85%E8%BF%87%E9%98%88%E5%80%BC%E7%9A%84%E6%9C%80%E5%B0%8F%E9%99%A4%E6%95%B0"><span class="nav-number">23.</span> <span class="nav-text">1283. 使结果不超过阈值的最小除数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#287-%E5%AF%BB%E6%89%BE%E9%87%8D%E5%A4%8D%E6%95%B0"><span class="nav-number">24.</span> <span class="nav-text">287. 寻找重复数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1011-%E5%9C%A8-D-%E5%A4%A9%E5%86%85%E9%80%81%E8%BE%BE%E5%8C%85%E8%A3%B9%E7%9A%84%E8%83%BD%E5%8A%9B"><span class="nav-number">25.</span> <span class="nav-text">1011. 在 D 天内送达包裹的能力</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#875-%E7%88%B1%E5%90%83%E9%A6%99%E8%95%89%E7%9A%84%E7%8F%82%E7%8F%82"><span class="nav-number">26.</span> <span class="nav-text">875. 爱吃香蕉的珂珂</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1292-%E5%85%83%E7%B4%A0%E5%92%8C%E5%B0%8F%E4%BA%8E%E7%AD%89%E4%BA%8E%E9%98%88%E5%80%BC%E7%9A%84%E6%AD%A3%E6%96%B9%E5%BD%A2%E7%9A%84%E6%9C%80%E5%A4%A7%E8%BE%B9%E9%95%BF"><span class="nav-number">27.</span> <span class="nav-text">1292. 元素和小于等于阈值的正方形的最大边长</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1300-%E8%BD%AC%E5%8F%98%E6%95%B0%E7%BB%84%E5%90%8E%E6%9C%80%E6%8E%A5%E8%BF%91%E7%9B%AE%E6%A0%87%E5%80%BC%E7%9A%84%E6%95%B0%E7%BB%84%E5%92%8C"><span class="nav-number">28.</span> <span class="nav-text">1300. 转变数组后最接近目标值的数组和</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#LCP-12-%E5%B0%8F%E5%BC%A0%E5%88%B7%E9%A2%98%E8%AE%A1%E5%88%92"><span class="nav-number">29.</span> <span class="nav-text">LCP 12. 小张刷题计划</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#410-%E5%88%86%E5%89%B2%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC"><span class="nav-number">30.</span> <span class="nav-text">410. 分割数组的最大值</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#NC82-%E5%88%86%E7%BB%84"><span class="nav-number">31.</span> <span class="nav-text">NC82.分组</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#1482-%E5%88%B6%E4%BD%9C-m-%E6%9D%9F%E8%8A%B1%E6%89%80%E9%9C%80%E7%9A%84%E6%9C%80%E5%B0%91%E5%A4%A9%E6%95%B0"><span class="nav-number">32.</span> <span class="nav-text">1482. 制作 m 束花所需的最少天数</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#378-%E6%9C%89%E5%BA%8F%E7%9F%A9%E9%98%B5%E4%B8%AD%E7%AC%ACK%E5%B0%8F%E7%9A%84%E5%85%83%E7%B4%A0"><span class="nav-number">33.</span> <span class="nav-text">378. 有序矩阵中第K小的元素</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#441-%E6%8E%92%E5%88%97%E7%A1%AC%E5%B8%81"><span class="nav-number">34.</span> <span class="nav-text">441. 排列硬币</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#174-%E5%9C%B0%E4%B8%8B%E5%9F%8E%E6%B8%B8%E6%88%8F"><span class="nav-number">35.</span> <span class="nav-text">174. 地下城游戏</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#848-%E5%8A%A0%E6%B2%B9%E7%AB%99%E4%B9%8B%E9%97%B4%E7%9A%84%E6%9C%80%E5%B0%8F%E8%B7%9D%E7%A6%BB%EF%BC%88LintCode%EF%BC%89"><span class="nav-number">36.</span> <span class="nav-text">848. 加油站之间的最小距离（LintCode）</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5489-%E4%B8%A4%E7%90%83%E4%B9%8B%E9%97%B4%E7%9A%84%E7%A3%81%E5%8A%9B"><span class="nav-number">37.</span> <span class="nav-text">5489. 两球之间的磁力</span></a></li></ol>
    </div>
</div>
        </aside>
    

    <div class="image-viewer-container">
    <img src="">
</div>


    
        <div class="search-pop-overlay">
    <div class="popup search-popup">
        <div class="search-header">
          <span class="search-input-field-pre">
            <i class="fas fa-keyboard"></i>
          </span>
            <div class="search-input-container">
                <input autocomplete="off"
                       autocorrect="off"
                       autocapitalize="off"
                       placeholder="搜索..."
                       spellcheck="false"
                       type="search"
                       class="search-input"
                >
            </div>
            <span class="popup-btn-close">
                <i class="fas fa-times"></i>
            </span>
        </div>
        <div id="search-result">
            <div id="no-result">
                <i class="fas fa-spinner fa-pulse fa-5x fa-fw"></i>
            </div>
        </div>
    </div>
</div>

    

</main>



<script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/utils.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/main.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/header-shrink.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/back2top.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/dark-light-toggle.js"></script>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/local-search.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/code-copy.js"></script>



    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/lazyload.js"></script>


<div class="post-scripts pjax">
    
        <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/left-side-toggle.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/anime.min.js"></script><script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/toc.js"></script>
    
</div>


    <script src="//cdn.jsdelivr.net/npm/hexo-theme-keep@3.4.3/source/js/libs/pjax.min.js"></script>
<script>
    window.addEventListener('DOMContentLoaded', () => {
        window.pjax = new Pjax({
            selectors: [
                'head title',
                '.page-container',
                '.pjax'
            ],
            history: true,
            debug: false,
            cacheBust: false,
            timeout: 0,
            analytics: false,
            currentUrlFullReload: false,
            scrollRestoration: false,
            // scrollTo: true,
        });

        document.addEventListener('pjax:send', () => {
            KEEP.utils.pjaxProgressBarStart();
        });

        document.addEventListener('pjax:complete', () => {
            KEEP.utils.pjaxProgressBarEnd();
            window.pjax.executeScripts(document.querySelectorAll('script[data-pjax], .pjax script'));
            KEEP.refresh();
        });
    });
</script>



<script src="https://cdn.jsdelivr.net/npm/live2d-widget@3.x/lib/L2Dwidget.min.js"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"debug":false,"model":{"jsonPath":"https://cdn.jsdelivr.net/npm/live2d-widget-model-hijiki@1.0.5/assets/hijiki.model.json"},"display":{"superSample":2,"width":160,"height":320,"position":"right","hOffset":0,"vOffset":-70},"mobile":{"show":false,"scale":0.2},"log":false});</script></body>
</html>
